Showing preview only (1,854K chars total). Download the full file or copy to clipboard to get everything.
Repository: PaloAltoNetworks/minemeld-core
Branch: master
Commit: d9c08b2a5a94
Files: 221
Total size: 1.7 MB
Directory structure:
gitextract_8s2k2lhp/
├── .circleci/
│ └── config.yml
├── .gitignore
├── AUTHORS
├── LICENSE
├── NOTICE
├── README.md
├── docs/
│ ├── Makefile
│ ├── architecture.rst
│ ├── conf.py
│ ├── configapi.rst
│ ├── index.rst
│ ├── internals.rst
│ ├── license.rst
│ ├── messages.rst
│ ├── metricsapi.rst
│ ├── nodeconfig.rst
│ ├── schema-indicator-0-1.json
│ ├── schema.rst
│ ├── scripts.rst
│ └── statusapi.rst
├── minemeld/
│ ├── __init__.py
│ ├── chassis.py
│ ├── collectd.py
│ ├── comm/
│ │ ├── __init__.py
│ │ └── zmqredis.py
│ ├── extensions/
│ │ ├── __init__.py
│ │ └── manager.py
│ ├── fabric.py
│ ├── flask/
│ │ ├── __init__.py
│ │ ├── aaa.py
│ │ ├── aaaapi.py
│ │ ├── cbfeed.py
│ │ ├── config.py
│ │ ├── configapi.py
│ │ ├── configdataapi.py
│ │ ├── events.py
│ │ ├── extensionsapi.py
│ │ ├── feedredis.py
│ │ ├── jobs.py
│ │ ├── jobsapi.py
│ │ ├── logger.py
│ │ ├── loginapi.py
│ │ ├── logsapi.py
│ │ ├── main.py
│ │ ├── metricsapi.py
│ │ ├── mmrpc.py
│ │ ├── prototypeapi.py
│ │ ├── redisclient.py
│ │ ├── session.py
│ │ ├── sns.py
│ │ ├── statusapi.py
│ │ ├── supervisorapi.py
│ │ ├── supervisorclient.py
│ │ ├── taxiicollmgmt.py
│ │ ├── taxiidiscovery.py
│ │ ├── taxiipoll.py
│ │ ├── taxiiutils.py
│ │ ├── tracedapi.py
│ │ ├── utils.py
│ │ └── validateapi.py
│ ├── ft/
│ │ ├── __init__.py
│ │ ├── actorbase.py
│ │ ├── anomali.py
│ │ ├── auscert.py
│ │ ├── autofocus.py
│ │ ├── azure.py
│ │ ├── bambenek.py
│ │ ├── base.py
│ │ ├── basepoller.py
│ │ ├── cif.py
│ │ ├── ciscoise.py
│ │ ├── cofense.py
│ │ ├── condition/
│ │ │ ├── BoolExpr.g4
│ │ │ ├── BoolExpr.tokens
│ │ │ ├── BoolExprLexer.py
│ │ │ ├── BoolExprLexer.tokens
│ │ │ ├── BoolExprListener.py
│ │ │ ├── BoolExprParser.py
│ │ │ ├── __init__.py
│ │ │ └── interface.py
│ │ ├── csv.py
│ │ ├── dag.py
│ │ ├── dag_ng.py
│ │ ├── google.py
│ │ ├── http.py
│ │ ├── ipop.py
│ │ ├── json.py
│ │ ├── local.py
│ │ ├── localdb.py
│ │ ├── logstash.py
│ │ ├── mm.py
│ │ ├── o365.py
│ │ ├── op.py
│ │ ├── panos.py
│ │ ├── phishme.py
│ │ ├── proofpoint.py
│ │ ├── recordedfuture.py
│ │ ├── redis.py
│ │ ├── st.py
│ │ ├── syslog.py
│ │ ├── table.py
│ │ ├── taxii.py
│ │ ├── taxii2.py
│ │ ├── test.py
│ │ ├── threatconnect.py
│ │ ├── threatq.py
│ │ ├── tmt.py
│ │ ├── utils.py
│ │ ├── visa.py
│ │ ├── vt.py
│ │ └── xmpp.py
│ ├── loader.py
│ ├── mgmtbus.py
│ ├── packages/
│ │ ├── __init__.py
│ │ ├── gdns/
│ │ │ ├── LICENSE
│ │ │ ├── __init__.py
│ │ │ ├── _ares.pyx
│ │ │ ├── cares.pxd
│ │ │ ├── cares_ntop.h
│ │ │ ├── cares_pton.h
│ │ │ ├── dig.py
│ │ │ └── dnshelper.c
│ │ ├── gevent_openssl/
│ │ │ ├── COPYING
│ │ │ ├── SSL.py
│ │ │ └── __init__.py
│ │ ├── ise/
│ │ │ ├── __init__.py
│ │ │ └── ers.py
│ │ └── panforest/
│ │ ├── __init__.py
│ │ └── forest.py
│ ├── run/
│ │ ├── __init__.py
│ │ ├── cacert_merge.py
│ │ ├── config.py
│ │ ├── console.py
│ │ ├── extgit.py
│ │ ├── freeze.py
│ │ ├── launcher.py
│ │ └── restore.py
│ ├── startupplanner.py
│ ├── supervisord/
│ │ ├── __init__.py
│ │ └── listener.py
│ └── traced/
│ ├── __init__.py
│ ├── main.py
│ ├── purge.py
│ ├── queryprocessor.py
│ ├── storage.py
│ └── writer.py
├── nodes.json
├── requirements-dev.txt
├── requirements-web.txt
├── requirements.txt
├── scripts/
│ └── prebuild-script.sh
├── setup.py
├── tests/
│ ├── comm_mock.py
│ ├── empty.yml
│ ├── feeds.htpasswd
│ ├── integration/
│ │ └── basic/
│ │ ├── DomainHC%3Fv%3Dcarbonblack.result
│ │ ├── IPv4.lst
│ │ ├── IPv4HC%3Fs%3D5%26n%3D10.result
│ │ ├── IPv4HC%3Fv%3Dcsv%26f%3Dconfidence%26f%3Dsources%7Cfeeds%26f%3Dindicator%7Cclientip%26tr%3D1.result
│ │ ├── IPv4HC%3Fv%3Djson%26tr%3D1.result
│ │ ├── IPv4HC%3Fv%3Djson-seq.result
│ │ ├── IPv4HC%3Fv%3Dmwg.result
│ │ ├── IPv4HC.result
│ │ ├── README.md
│ │ ├── URL.lst
│ │ ├── URLHC%3Fs%3D5%26n%3D10.result
│ │ ├── URLHC%3Fv%3Dbluecoat%26cd%3Dtest.result
│ │ ├── URLHC%3Fv%3Dbluecoat.result
│ │ ├── URLHC%3Fv%3Dcsv%26f%3Dconfidence%26f%3Dsources%7Cfeeds%26f%3Dindicator%7Curl.result
│ │ ├── URLHC%3Fv%3Djson%26tr%3D1.result
│ │ ├── URLHC%3Fv%3Djson-seq.result
│ │ ├── URLHC%3Fv%3Dmwg.result
│ │ ├── URLHC%3Fv%3Dpanosurl%26di%3D1.result
│ │ ├── URLHC%3Fv%3Dpanosurl%26sp%3D1%26nsl%3D1.result
│ │ ├── URLHC%3Fv%3Dpanosurl%26sp%3D1.result
│ │ ├── URLHC%3Fv%3Dpanosurl.result
│ │ ├── URLHC.result
│ │ ├── domain.lst
│ │ ├── gen-results.sh
│ │ └── test.py
│ ├── panos_mock.py
│ ├── st_profile.py
│ ├── test-prototype-1.yml
│ ├── test_comm_amqp.py
│ ├── test_device_list.yml
│ ├── test_device_list2.yml
│ ├── test_flask_aaa.py
│ ├── test_ft_autofocus.py
│ ├── test_ft_base.py
│ ├── test_ft_basepoller.py
│ ├── test_ft_boolexpr.py
│ ├── test_ft_dag.py
│ ├── test_ft_dag_devicepusher_op__show__object__registered_ip__ip_192_168_1_1__ip___registered_ip___object___show__0.xml
│ ├── test_ft_dag_devicepusher_op__show__object__registered_ip__ip_192_168_1_2__ip___registered_ip___object___show__0.xml
│ ├── test_ft_dag_devicepusher_op__show__object__registered_ip__tag__entry_name__mmeld_test_____tag___registered_ip___object___show__0.xml
│ ├── test_ft_ipop.py
│ ├── test_ft_local.py
│ ├── test_ft_logstash.py
│ ├── test_ft_op.py
│ ├── test_ft_redis.py
│ ├── test_ft_st.py
│ ├── test_ft_syslog.py
│ ├── test_ft_table.py
│ ├── test_ft_taxii.py
│ ├── test_ft_taxii_stix_package_IPv4_1_3.xml
│ ├── test_ft_taxii_stix_package_IPv4_3_1.xml
│ ├── test_ft_taxii_stix_package_IPv4_3_2.xml
│ ├── test_ft_taxii_stix_package_IPv6_3_1.xml
│ ├── test_ft_taxii_stix_package_IPv6_3_2.xml
│ ├── test_localdb.yml
│ ├── test_localdb2.yml
│ ├── test_run_config.py
│ ├── test_startupplanner.py
│ ├── test_traced_queryprocessor.py
│ ├── test_traced_storage.py
│ ├── test_traced_writer.py
│ ├── testproto.yml
│ ├── traced_mock.py
│ ├── traced_storage_profile.py
│ └── wsgi.htpasswd
└── tox.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: .circleci/config.yml
================================================
version: 2.1
orbs:
aws-s3: circleci/aws-s3@1.0.4
jobs:
build-bionic:
docker:
- image: circleci/buildpack-deps:bionic
steps:
- run:
name: Update & Upgrade
command: sudo apt update && sudo apt upgrade -y
- checkout
- run:
name: Install deps
command: >
sudo apt install -y gcc git python-minimal python2.7-dev
libffi-dev libssl-dev make g++ libleveldb-dev librrd-dev
libxslt1-dev libc-ares-dev libsnappy-dev python-pip
- run:
name: Install Python dev requirements
command: sudo -H pip install -r requirements-dev.txt
- run:
name: Show Python Version
command: /usr/bin/env python -V
- run:
name: Build package
command: >
platter build --virtualenv-version 16.7.9 -r requirements-web.txt
--prebuild-script scripts/prebuild-script.sh
- run:
name: Rename files
command: for file in dist/*; do mv "$file" "${file%.tar.gz}.$CIRCLE_SHA1.bionic"; done
- persist_to_workspace:
root: dist
paths:
- .
build-xenial:
docker:
- image: circleci/buildpack-deps:xenial
steps:
- run:
name: Update & Upgrade
command: sudo apt update && sudo apt upgrade -y
- checkout
- run:
name: Install deps
command: >
sudo apt install -y gcc git python-minimal python2.7-dev
libffi-dev libssl-dev make g++ libleveldb-dev librrd-dev
libxslt1-dev libc-ares-dev libsnappy-dev python-pip
- run:
name: Install Python dev requirements
command: sudo -H pip install -r requirements-dev.txt
- run:
name: Show Python Version
command: /usr/bin/env python -V
- run:
name: Build package
command: >
platter build --virtualenv-version 16.7.9 -r requirements-web.txt
--prebuild-script scripts/prebuild-script.sh
- run:
name: Rename files
command: for file in dist/*; do mv "$file" "${file%.tar.gz}.$CIRCLE_SHA1.xenial"; done
- persist_to_workspace:
root: dist
paths:
- .
deploy:
docker:
- image: circleci/python:2.7
steps:
- run:
name: Create workspace dir
command: mkdir ~/workspace
- attach_workspace:
at: ~/workspace
- run:
name: Workspace contents
command: find ~/workspace
- aws-s3/sync:
from: ~/workspace
to: 's3://minemeld/'
arguments: |
--acl public-read
workflows:
version: 2
xenial:
jobs:
- build-xenial:
filters:
tags:
only: '/.*/'
- deploy:
requires:
- build-xenial
filters:
branches:
ignore: '/.*/'
tags:
only: '/.*/'
bionic:
jobs:
- build-bionic:
filters:
tags:
only: '/.*/'
- deploy:
requires:
- build-bionic
filters:
branches:
ignore: '/.*/'
tags:
only: '/.*/'
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# PyCharm
.idea/
.vscode/
_ares.c
_ares.h
================================================
FILE: AUTHORS
================================================
Luigi Mori <lmori@paloaltonetworks.com>
Kevin Steves <ksteves@paloaltonetworks.com>
Phil Da Silva <pdasilva@paloaltonetworks.com>
Kevin Stilwell <kevin.stilwell@phishme.com>
iDev <zero.line@gmail.com>
Jonas Eichinger <jonas.eichinger@unisys.com>
Egon Kidmose <kidmose@gmail.com>
Dan James <sddj@me.com>
Ben Carroll <bcarroll@paloaltonetworks.com>
John Marion <jmarion-ext@arista.com>
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: NOTICE
================================================
MineMeld Core
Copyright 2016 Palo Alto Networks
This product includes software developed at
Palo Alto Networks Inc. (http://www.paloaltonetworks.com/).
================================================
FILE: README.md
================================================
# minemeld-core
This repo contains the code for the engine and the API of MineMeld, an extensible Threat Intelligence processing framework.
For details check the MineMeld [Wiki](https://github.com/PaloAltoNetworks/minemeld/wiki)
================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/minemeld.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/minemeld.qhc"
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/minemeld"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/minemeld"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
================================================
FILE: docs/architecture.rst
================================================
Architecture
============
Processing graph
----------------
The core processing engine of MineMeld is based on a Direct Acyclic Graph
of nodes. Indicators are retrieved or received by Miner nodes and then pushed to
downstream nodes via *update* messages. Nodes can also signal to downstream
nodes the removal of an indicator (in case of expiration, ...) by sending
a *withdraw* message.
Each node in the graph is independent from other nodes, there is no global
state or global clock inside the engine. All the nodes are independent and
asynchrnous. Each node is also responsabile for maintaining its own state.
This architecture trades memory and disk for flexibility.
.. image:: images/updates.png
.. image:: images/withdraws.png
Node
----
Each node may have 0 or more inputs and 0 or more output. Rather obviuosly
if a node has 0 inputs it is considered a Miner node, if a node has 0 ouput
it is considered an Output node.
Each node also offers a RPC interface, for direct out of band requests, and
a connection to a *management bus* for status checks and management commands
coming from the *management bus master*.
.. image:: images/nodes.png
The connections between nodes are implemented with a pubsub mechanism over
the *fabric*. Each node sends its downstream message to a *topic* named as
the node, and all the downstream nodes are subscribers of this topic.
.. image:: images/topics.png
Runtime architecture
--------------------
To take advantage of all the cores available on the system, the engine
by default automatically splits the nodes of the graph into multiple
processes called *chassis*. Each *chassis* has a dedicated connection
to the *fabric* and to the *management bus*.
The *master* process monitors the health and the metrics of each *chassis*
using the *management bus*. The *master* process is also responsible for
synchronzing the nodes when the engine starts and stops, to ensure that
the state of the graph is consistent. At shutdown this is achieved
using a super simplified version of the Chandy-Lamport checkpoint
algorithm.
Both the *management bus* and the *fabric* are implemented using an
external message broker, RabbitMQ.
.. image:: images/chassis-architecture.png
================================================
FILE: docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# minemeld-core documentation build configuration file, created by
# sphinx-quickstart on Thu Aug 6 14:14:33 2015.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# flake8: noqa
import sys
import os
import shlex
# from http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/
import mock
MOCK_MODULES = ['plyvel']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = mock.Mock()
# 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.
sys.path.insert(0, os.path.abspath('..'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'minemeld-core'
copyright = u'2015, Palo Alto Networks'
author = u'Palo Alto Networks'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.9'
# The full version, including alpha/beta/rc tags.
release = '0.9.70.post5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- 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'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# 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']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'minemeld-coredoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'minemeld-core.tex', u'modindex_common_prefixer-wagon Documentation',
u'Palo Alto Networks', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'minemeld-core', u'minemeld-core Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'minemeld-core', u'minemeld-core Documentation',
author, 'minemeld-core', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
================================================
FILE: docs/configapi.rst
================================================
Configuration API
=================
Configuration API can be used to change a temporary configuration. The temp
configuration is applied when the /config/commit API is called.
The temp configuration has a *version* attribute. The version changes
every time the temp configuration is reinitialized or reloaded from
the current MineMeld running configuration. Some API calls (commit,
create node, ...) require a version parameter, if the supplied version
is different from the current temp config version a 409 error is returned.
Each node has a *version* attribute. The node version changes every time
the node config is changed. Some API calls (set node, ...) require a version
parameter. If the supplied version is different from the current node version
a 409 error is returned.
Authentication
--------------
Authentication is performed via basic authentication. A 401 error is returned
in case of invalid credentials:
::
$ curl -u 'admin:goodpassword' -i http://127.0.0.1/config/info
HTTP/1.1 200 OK
[...]
$ curl -u 'admin:baspassword' -i http://127.0.0.1/config/info
HTTP/1.1 401 UNAUTHORIZED
[...]
.. warning:: Use HTTPS with a trusted certificate in production !
Configuration information
-------------------------
::
$ curl -u 'admin:admin' -i http://127.0.0.1/config/info
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 06 Sep 2015 14:51:41 GMT
Content-Type: application/json
Content-Length: 141
Connection: keep-alive
{
"result": {
"fabric": false,
"mgmtbus": false,
"num_nodes": 8,
"version": "58102565-1b93-4095-9130-84556496b84b"
}
}
Reload configuration
--------------------
Reload current running configuration as temporary configuration. Config version
is changed. Returns new config version.
::
$ curl -u 'admin:admin' -i http://127.0.0.1/config/reload
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 06 Sep 2015 14:52:46 GMT
Content-Type: application/json
Content-Length: 54
Connection: keep-alive
{
"result": "b2482473-1e9f-4a24-a8b7-7296f1dfb856"
}
Create node
-----------
Create a new node. *version* attribute is required, and should be the config
version. Returns the new node id and version.
::
$ curl -XPOST -H 'Content-Type: application/json' -u 'admin:admin' -i http://127.0.0.1/config/node -d '{
"name": "spamhaus_EDROP2",
"properties": {
"class": "HTTP",
"config": {
"attributes": {
"direction": "inbound",
"type": "IPv4"
},
"cchar": ";",
"source_name": "http://www.spamhaus.org/drop/edrop.txt",
"split_char": ";",
"url": "http://www.spamhaus.org/drop/edrop.txt"
},
"output": true
},
"version": "b2482473-1e9f-4a24-a8b7-7296f1dfb856"
}'
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 06 Sep 2015 14:59:28 GMT
Content-Type: application/json
Content-Length: 91
Connection: keep-alive
{
"result": {
"id": 9,
"version": "b2482473-1e9f-4a24-a8b7-7296f1dfb856+0"
}
}
Get node configuration
----------------------
::
$ curl -u 'admin:admin' -i http://127.0.0.1/config/node/9
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 06 Sep 2015 15:01:00 GMT
Content-Type: application/json
Content-Length: 479
Connection: keep-alive
{
"result": {
"name": "spamhaus_EDROP2",
"properties": {
"class": "HTTP",
"config": {
"attributes": {
"direction": "inbound",
"type": "IPv4"
},
"cchar": ";",
"source_name": "http://www.spamhaus.org/drop/edrop.txt",
"split_char": ";",
"url": "http://www.spamhaus.org/drop/edrop.txt"
},
"output": true
},
"version": "b2482473-1e9f-4a24-a8b7-7296f1dfb856+0"
}
}
Change node configuration
-------------------------
*version* is the current node version.
::
$ curl -XPUT -u 'admin:admin' -H 'Content-Type: application/json' -i http://127.0.0.1/config/node/8 -d '{
"name": "spamhaus_EDROP2",
"properties": {
"class": "HTTP",
"config": {
"attributes": {
"direction": "inbound",
"type": "IPv4"
},
"cchar": ";",
"source_name": "http://www.spamhaus.org/drop/edrop2.txt",
"split_char": ";",
"url": "http://www.spamhaus.org/drop/edrop.txt"
},
"output": true
},
"version": "b2482473-1e9f-4a24-a8b7-7296f1dfb856+0"
}'
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 06 Sep 2015 15:24:25 GMT
Content-Type: application/json
Content-Length: 56
Connection: keep-alive
{
"result": "b2482473-1e9f-4a24-a8b7-7296f1dfb856+1"
}
Delete node
-----------
Delete a node. *version* is the current node version.
::
$ curl -XDELETE -H 'Content-type: application/json' -u 'admin:admin' -i http://127.0.0.1/config/node/9 -d '{"version": "b2482473-1e9f-4a24-a8b7-7296f1dfb856+0"}'
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 06 Sep 2015 15:17:42 GMT
Content-Type: application/json
Content-Length: 20
Connection: keep-alive
{
"result": "OK"
}
Commit configuration
--------------------
*version* is the current configuration version.
::
$ curl -XPOST -H 'Content-Type: application/json' -u 'admin:admin' -i http://127.0.0.1/config/commit -d '{"version": "b2482473-1e9f-4a24-a8b7- 7296f1dfb856"}'
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Sun, 06 Sep 2015 15:31:26 GMT
Content-Type: application/json
Content-Length: 20
Connection: keep-alive
{
"result": "OK"
}
================================================
FILE: docs/index.rst
================================================
.. MineMeld documentation master file, created by
sphinx-quickstart on Thu Aug 6 14:14:33 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to MineMeld's documentation!
=======================================
Contents:
.. toctree::
:maxdepth: 1
architecture
messages
scripts
schema
statusapi
configapi
metricsapi
internals
license
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
================================================
FILE: docs/internals.rst
================================================
Internals
=========
minemeld.ft.table
-------------------
.. automodule:: minemeld.ft.table
minemeld.ft.st
----------------
.. automodule:: minemeld.ft.st
================================================
FILE: docs/license.rst
================================================
LICENSE
=======
Copyright (c) 2015, Palo Alto Networks <techbizdev@paloaltonetworks.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
================================================
FILE: docs/messages.rst
================================================
Messages
========
Intra-node protocol
-------------------
The protocol used between nodes is super simple. There are 3 messages:
update
******
update(indicator, value)
:indicator: string
:value: a dictionary of attributes for the indicator
Notifies a new indicator or an update of the attributes associated to an
indicator.
withdraw
********
withdraw(indicator[, value])
:indicator: string
:value: (optional) a dictionary of attributes for the indicator
Notifies a withdraw of the indicator
checkpoint
**********
checkpoint(id)
Used as a processing barrier for the graph when the graph is being stopped.
================================================
FILE: docs/metricsapi.rst
================================================
Metrics API
===========
Metrics API can be used to retrieve historical statistics of the system and
MineMeld nodes.
Metrics list
------------
::
$ curl -i -u 'admin:admin' http://127.0.0.1/metrics
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 08 Sep 2015 21:41:07 GMT
Content-Type: application/json
Content-Length: 1040
Connection: keep-alive
{
"result": [
"spamhaus_EDROP.update.tx",
"df-run",
"inboundaggregator.update.rx",
"dshield_blocklist.length",
"df-run-user",
"zeustracker_badips.length",
"spamhaus_DROP.length",
"df-root",
"df-sys-fs-cgroup",
"spamhaus_EDROP.length",
[...]
]
}
Metric history
--------------
Metric history can be retrieved using /metrics/<metric name> endpoint.
::
$ curl -i -u 'admin:admin' http://127.0.0.1/metrics/outboundaggregator.length
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 08 Sep 2015 21:42:52 GMT
Content-Type: application/json
Content-Length: 1779
Connection: keep-alive
{
"result": [
[
1441661340,
null
],
[...]
]
}
================================================
FILE: docs/nodeconfig.rst
================================================
Node config
===========
The set of config parameters supported by a node depends on the node class.
.. note::
This document has been extracted from the docstrings of the python code.
For the most updated documentation check the original source code.
Base class
----------
All nodes support these parameters.
Parameters
+++++++++++++++++
:infilters: inbound *filter set*. Filters to apply to received indicators.
:outfilters: outbound *filter set*. Filters to apply to transmitted
indicators.
Filter set
++++++++++
Each filter set is a list of filters. Filters are checked from top
to bottom, the first matching filter is applied and following filters are not
checked. Default action is **accept**.
Each filter is a dictionary with 3 keys:
:name: name of the filter.
:conditions: list of boolean expressions to match on the
indicator and indicator value.
:actions: list of actions to apply to the indicator.
Currently the only supported actions are **accept** and **drop**
In addition to the atttributes in the indicator value, filters can
match on 3 special attributes:
:__indicator: the indicator itself.
:__method: the method of the message, **update** or **withdraw**.
:__origin: the name of the node who sent the indicator.
Condition
+++++++++
A condition in the filter is a boolean expression composed by: a JMESPath
expression, an operator (<, <=, ==, >=, >, !=) and a value.
Example
+++++++
Example config in YAML::
infilters:
- name: accept withdraws
conditions:
- __method == 'withdraw'
actions:
- accept
- name: accept URL
conditions:
- type == 'URL'
actions:
- accept
- name: drop all
actions:
- drop
outfilters:
- name: accept all (default)
actions:
- accept
Base poller class
-----------------
In addition to `Base class` config parameters, the base poller class support
the following parameters.
Config parameters
+++++++++++++++++
:source_name: name of the source. This is added to the
*sources* attribute of the generated indicators. Default: name
of the node.
:attributes: dictionary of attributes for the generated indicators.
This dictionary is used as template for the value of the generated
indicators. Default: empty
:interval: polling interval in seconds. Default: 3600.
:num_retries: how many times the miner should try to reach the source in case
of failure. If this number is exceeded, the miner
waits until the next polling time to try again. Default: 2
:age_out: age out policies to apply to the indicators.
Default: age out check interval 3600 seconds, sudden death enabled,
default age out interval 30 days.
Age out policy
++++++++++++++
Age out policy is described by a dictionary with at least 3 keys:
:interval: number of seconds between successive age out checks.
:sudden_death: boolean, if *true* indicators are immediately aged out
when they disappear from the feed.
:default: age out interval. After this interval an indicator is aged
out even if it is still present in the feed. If *null*, no age out
interval is applied.
Additional keys can be used to specify age out interval per indicator
*type*.
Age out interval
++++++++++++++++
Age out intervals have the following format::
<base attribute>+<interval>
*base attribute* can be *last_seen*, if the age out interval should be
calculated based on the last time the indicator was found in the feed,
or *first_seen*, if instead the age out interval should be based on the
time the indicator was first seen in the feed. If not specified
*first_seen* is used.
*interval* is the length of the interval expressed in seconds. Suffixes
*d*, *h* and *m* can be used to specify days, hours or minutes.
Example
+++++++
Example config in YAML for a feed where indicators should be aged out
only when they are removed from the feed::
source_name: example.persistent_feed
interval: 600
age_out:
default: null
sudden_death: true
interval: 300
attributes:
type: IPv4
confidence: 100
share_level: green
direction: inbound
Example config in YAML for a feed where indicators are aged out when
they disappear from the feed and 30 days after they have seen for the
first time in the feed::
source_name: example.long_running_feed
interval: 3600
age_out:
default: first_seen+30d
sudden_death: true
interval: 1800
attributes:
type: URL
confidence: 50
share_level: green
Example config in YAML for a feed where indicators are aged 30 days
after they have seen for the last time in the feed::
source_name: example.delta_feed
interval: 3600
age_out:
default: last_seen+30d
sudden_death: false
interval: 1800
attributes:
type: URL
confidence: 50
share_level: green
minemeld.ft.http.HttpFT
-----------------------
In addition to `Base poller class` config parameters, the base poller class
support the following parameters.
Parameters
+++++++++++++++++
:url: URL of the feed.
:polling_timeout: timeout of the polling request in seconds.
Default: 20
:verify_cert: boolean, if *true* feed HTTPS server certificate is
verified. Default: *true*
:ignore_regex: Python regular expression for lines that should be
ignored. Default: *null*
:indicator: an *extraction dictionary* to extract the indicator from
the line. If *null*, the text until the first whitespace or newline
character is used as indicator. Default: *null*
:fields: a dicionary of *extraction dictionaries* to extract
additional attributes from each line. Default: {}
Extraction dictionary
+++++++++++++++++++++
Extraction dictionaries contain the following keys:
:regex: Python regular expression for searching the text.
:transform: template to generate the final value from the result
of the regular expression. Default: the entire match of the regex
is used as extracted value.
See Python `re <https://docs.python.org/2/library/re.html>`_ module for
details about Python regular expressions and templates.
Example
+++++++
Example config in YAML where extraction dictionaries are used to
extract the indicator and additional fields::
url: https://www.dshield.org/block.txt
ignore_regex: "[#S].*"
indicator:
regex: '^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\t([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'
transform: '\1-\2'
fields:
dshield_nattacks:
regex: '^.*\t.*\t[0-9]+\t([0-9]+)'
transform: '\1'
dshield_name:
regex: '^.*\t.*\t[0-9]+\t[0-9]+\t([^\t]+)'
transform: '\1'
dshield_country:
regex: '^.*\t.*\t[0-9]+\t[0-9]+\t[^\t]+\t([A-Z]+)'
transform: '\1'
dshield_email:
regex: '^.*\t.*\t[0-9]+\t[0-9]+\t[^\t]+\t[A-Z]+\t(\S+)'
transform: '\1'
Example config in YAML where the text in each line until the first
whitespace is used as indicator::
url: https://ransomwaretracker.abuse.ch/downloads/CW_C2_URLBL.txt
ignore_regex: '^#'
For a complete config example check **dshield.block** prototype.
minemeld.ft.csv.CSVFT
---------------------
In addition to `Base poller class` config parameters, the base poller class
support the following parameters.
Parameters
++++++++++
:url: URL of the feed.
:polling_timeout: timeout of the polling request in seconds.
Default: 20
:verify_cert: boolean, if *true* feed HTTPS server certificate is
verified. Default: *true*
:ignore_regex: Python regular expression for lines that should be
ignored. Default: *null*
:fieldnames: list of field names in the file. If *null* the values
in the first row of the file are used as names. Default: *null*
:delimiter: see `csv Python module <https://docs.python.org/2/library/csv.html#dialects-and-formatting-parameters>`_.
Default: ,
:doublequote: see `csv Python module <https://docs.python.org/2/library/csv.html#dialects-and-formatting-parameters>`_.
Default: true
:escapechar: see `csv Python module <https://docs.python.org/2/library/csv.html#dialects-and-formatting-parameters>`_.
Default: null
:quotechar: see `csv Python module <https://docs.python.org/2/library/csv.html#dialects-and-formatting-parameters>`_.
Default: "
:skipinitialspace: see `csv Python module <https://docs.python.org/2/library/csv.html#dialects-and-formatting-parameters>`_.
Default: false
Example
+++++++
Example config in YAML::
url: https://sslbl.abuse.ch/blacklist/sslipblacklist.csv
ignore_regex: '^#'
fieldnames:
- indicator
- port
- sslblabusech_type
For a complete config example check **sslabusech.ipblacklist** prototype.
minemeld.ft.json.SimpleJSON
---------------------------
In addition to `Base poller class` config parameters, the base poller class
support the following parameters.
Parameters
++++++++++
:url: URL of the feed.
:polling_timeout: timeout of the polling request in seconds.
Default: 20
:verify_cert: boolean, if *true* feed HTTPS server certificate is
verified. Default: *true*
:extractor: JMESPath expression for extracting the indicators from
the JSON document. Default: @
:indicator: the JSON attribute to use as indicator. Default: indicator
:fields: list of JSON attributes to include in the indicator value.
If *null* no additional attributes are extracted. Default: *null*
:prefix: prefix to add to field names. Default: json
Example
+++++++
Example config in YAML::
url: https://ip-ranges.amazonaws.com/ip-ranges.json
extractor: "prefixes[?service=='AMAZON']"
prefix: aws
indicator: ip_prefix
fields:
- region
- service
For a complete config example check **aws.AMAZON** prototype.
================================================
FILE: docs/schema-indicator-0-1.json
================================================
{
"id": "https://www.paloaltonetworks.com/minemeld-indicator-schema-0-1#",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "schema for minemeld attributes",
"type": "object",
"required": [ "type" ],
"properties": {
"type": {
"description": "type of the indicator",
"type": "string",
"enum": [
"IPv4",
"IPv6",
"domain",
"URL",
"sha512",
"sha256",
"sha1",
"md5",
"ssdeep",
"mutex",
"windows-registry-value",
"user-agent.fragment",
"file.name",
"process.command_line",
"email-addr",
"autonomous-system"
]
},
"direction": {
"description": "direction of the session, applies to IPv4",
"type": "string",
"enum": ["inbound", "outbound"]
},
"first_seen": {
"type": "integer",
"format": "utc-millisec",
"description": "time the indicator has been seen for the first time. <"
},
"last_seen": {
"type": "integer",
"format": "utc-millisec",
"description": "time the indicator has been seen for the last time. >"
},
"sources": {
"description": "list of sources for this indicator",
"type": "array",
"items": {
"type": "string",
"format": "uri"
}
},
"confidence": {
"type": "integer",
"description": "confidence in the indicator 0-100",
"minimum": 0,
"maximum": 100
},
"share_level": {
"description": "share level of indicator",
"type": "string",
"enum": ["white", "green", "amber", "red"]
},
"country": {
"type": "string",
"description": "ISO country code (IPv4 and IPv6 only)",
"minLength": 2,
"maxLength": 2
},
"AS": {
"type": "string",
"description": "Autonmous system (IPv4 and IPv6 only)"
}
},
"patternProperties": {
"^_[a-zA-Z0-9$_]*$": {
"description": "private properties"
},
"^$[a-zA-Z0-9$_]*$": {
"description": "reserved, temporary properties"
}
}
}
================================================
FILE: docs/schema.rst
================================================
Indicator value schema
======================
.. literalinclude:: schema-indicator-0-1.json
:language: json
:linenos:
================================================
FILE: docs/scripts.rst
================================================
mm-run
=========
mm-run is a simple script that can be used as frontend to the minemeld library.
Usage
-----
::
$ mm-run --help
usage: mm-run.py [-h] [--version] [--multiprocessing NP] [--verbose] CONFIG
Low-latency threat indicators processor
positional arguments:
CONFIG path of the config file or of the config directory
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
--multiprocessing NP enable multiprocessing. NP is the number of processes,
0 to use a process per machine core
--verbose verbose
Configuration
-------------
CONFIG parameter on the command line can point to a configuration file or to a
configuration directory. If CONIG is a directory, mm-run will check for
commited-config.yml and running-config.yml files. If only running-config.yml exists,
mm-run assumes that the config has not been changed and the processing continues
where it was stopped. If only canidate-config.yml exists, mm-run copies the
file to running-config.yml and reinitializes the processing. If both files exist,
candidate-config.yml is copied over running-config.yml and the processing is
reinitialized if the 2 files are different. If CONFIG instead is a path to a
configuration file, the configuration will be considered as new and the processing
is reinitialized.
nodes
~~~~~
The **nodes** section contains the desription of the processing DAG. It is composed
by a list of descriptions of nodes.
Each node config has the following general format:
::
nodename: # name of the node
config:
# list of parameters for the node, depends on the node class
class: nodeclass # class of the node
inputs:
# list of upstream nodes
- node1
- node2
output: true|false # if the node should generate updates & withdraws
Node can also be based on prototypes, in that case the *config* and *class*
sections are omitted as they are specified inside the prototype.
::
nodename: # name of the node
prototype: prototype1 # name of the prototype to be used
inputs:
# list of upstream nodes
- node1
- node2
output: true|false # if the node should generate updates & withdraws
Example 1
^^^^^^^^^
::
spamhaus_DROP:
config:
source_name: http://www.spamhaus.org/drop/drop.txt
attributes:
type: IPv4
direction: inbound
cchar: ;
split_char: ;
url: http://www.spamhaus.org/drop/drop.txt
class: HTTP
output: true
This describes a node with the following properties:
:name: spamhaus_DROP
:class: HTTP
:inputs: *none*, this is a Miner
:output: enabled, this node will emit indicators
:config: specific configuration for this node class
Example 2
^^^^^^^^^
::
inboundaggregator:
config:
infilters:
- name: accept inbound IPv4
conditions:
- type == 'IPv4'
- direction == 'inbound'
actions:
- accept
- name: drop all
actions:
- drop
class: AggregatorIPv4
output: true
inputs:
- spamhaus_DROP
- spamhaus_EDROP
- dshield_blocklist
:name: inboundaggregator
:class: AggregatorIPv4
:inputs: this node will receive indicators from spamhaus_DROP, spamhaus_EDROP, ...
:output: enabled, this node will emit indicators
:config: specific configuration for this node class
Example 3
^^^^^^^^^
::
spamhaus_DROP:
output: true
prototype: spamhaus.DROP
:name: spamhaus_DROP
:inputs: *none*, this is a Miner
:output: enabled, this node will emit indicators
:prototype: *config* and *class* of this node will be loaded from the spamhaus.DROP prototype
================================================
FILE: docs/statusapi.rst
================================================
Status API
==========
Status API can be used to retrieve status information about minemeld core
engine and the system.
MineMeld status
---------------
::
$ curl -i -u 'admin:admin' http://127.0.0.1/status/minemeld
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 08 Sep 2015 21:34:47 GMT
Content-Type: application/json
Content-Length: 1878
Connection: keep-alive
{
"result": {
"dshield_blocklist": {
"inputs": [],
"length": 20,
"output": true,
"state": 5,
"statistics": {
"update.tx": 20
}
},
[...]
}
System status
-------------
Reports percent usage of CPUs, disk, memory and swap.
::
$curl -i -u 'admin:admin' http://127.0.0.1/status/system
HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Tue, 08 Sep 2015 21:37:31 GMT
Content-Type: application/json
Content-Length: 108
Connection: keep-alive
{
"result": {
"cpu": [
0.0
],
"disk": 17.7,
"memory": 25.1,
"swap": 0.0
}
}
================================================
FILE: minemeld/__init__.py
================================================
"""
minemeld
========
MineMeld core engine
"""
__version__ = '0.9.70.post5'
================================================
FILE: minemeld/chassis.py
================================================
# Copyright 2015-2016 Palo Alto Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
minemeld.chassis
A chassis instance contains a list of nodes and a fabric.
Nodes communicate using the fabric.
"""
import os
import logging
import gevent
import gevent.queue
import gevent.monkey
gevent.monkey.patch_all(thread=False, select=False)
import minemeld.mgmtbus
import minemeld.ft
import minemeld.fabric
LOG = logging.getLogger(__name__)
STATE_REPORT_INTERVAL = 10
class Chassis(object):
"""Chassis class
Args:
fabricclass (str): class for the fabric
fabricconfig (dict): config dictionary for fabric,
class specific
mgmtbusconfig (dict): config dictionary for mgmt bus
"""
def __init__(self, fabricclass, fabricconfig, mgmtbusconfig):
self.chassis_id = os.getpid()
self.fts = {}
self.poweroff = gevent.event.AsyncResult()
self.fabric_class = fabricclass
self.fabric_config = fabricconfig
self.fabric = minemeld.fabric.factory(
self.fabric_class,
self,
self.fabric_config
)
self.mgmtbus = minemeld.mgmtbus.slave_hub_factory(
mgmtbusconfig['slave'],
mgmtbusconfig['transport']['class'],
mgmtbusconfig['transport']['config']
)
self.mgmtbus.add_failure_listener(self.mgmtbus_failed)
self.mgmtbus.request_chassis_rpc_channel(self)
self.log_channel_queue = gevent.queue.Queue(maxsize=128)
self.log_channel = self.mgmtbus.request_log_channel()
self.log_glet = None
self.status_channel_queue = gevent.queue.Queue(maxsize=128)
self.status_glet = None
def _dynamic_load(self, classname):
modname, classname = classname.rsplit('.', 1)
imodule = __import__(modname, globals(), locals(), [classname])
cls = getattr(imodule, classname)
return cls
def get_ft(self, ftname):
return self.fts.get(ftname, None)
def configure(self, config):
"""configures the chassis instance
Args:
config (list): list of FTs
"""
newfts = {}
for ft in config:
ftconfig = config[ft]
LOG.debug(ftconfig)
# new FT
newfts[ft] = minemeld.ft.factory(
ftconfig['class'],
name=ft,
chassis=self,
config=ftconfig.get('config', {})
)
newfts[ft].connect(
ftconfig.get('inputs', []),
ftconfig.get('output', False)
)
self.fts = newfts
# XXX should be moved to constructor
self.mgmtbus.start()
self.fabric.start()
self.mgmtbus.send_master_rpc(
'chassis_ready',
params={'chassis_id': self.chassis_id},
timeout=10
)
def request_mgmtbus_channel(self, ft):
self.mgmtbus.request_channel(ft)
def request_rpc_channel(self, ftname, ft, allowed_methods=None):
if allowed_methods is None:
allowed_methods = []
self.fabric.request_rpc_channel(ftname, ft, allowed_methods)
def request_pub_channel(self, ftname):
return self.fabric.request_pub_channel(ftname)
def request_sub_channel(self, ftname, ft, subname, allowed_methods=None):
if allowed_methods is None:
allowed_methods = []
self.fabric.request_sub_channel(ftname, ft, subname, allowed_methods)
def send_rpc(self, sftname, dftname, method, params, block, timeout):
return self.fabric.send_rpc(sftname, dftname, method, params,
block=block, timeout=timeout)
def _log_actor(self):
while True:
try:
params = self.log_channel_queue.get()
self.log_channel.publish(
method='log',
params=params
)
except Exception:
LOG.exception('Error sending log')
def log(self, timestamp, nodename, log_type, value):
self.log_channel_queue.put({
'timestamp': timestamp,
'source': nodename,
'log_type': log_type,
'log': value
})
def _status_actor(self):
while True:
try:
params = self.status_channel_queue.get()
self.mgmtbus.send_status(
params=params
)
except Exception:
LOG.exception('Error publishing status')
def publish_status(self, timestamp, nodename, status):
self.status_channel_queue.put({
'timestamp': timestamp,
'source': nodename,
'status': status
})
def fabric_failed(self):
self.stop()
def mgmtbus_failed(self):
LOG.critical('chassis - mgmtbus failed')
self.stop()
def mgmtbus_start(self):
LOG.info('chassis - start received from mgmtbus')
self.start()
return 'ok'
def fts_init(self):
for ft in self.fts.values():
if ft.get_state() < minemeld.ft.ft_states.INIT:
return False
return True
def stop(self):
LOG.info("chassis stop called")
if self.log_glet is not None:
self.log_glet.kill()
if self.status_glet is not None:
self.status_glet.kill()
if self.fabric is None:
return
for ftname, ft in self.fts.iteritems():
try:
ft.stop()
except:
LOG.exception('Error stopping {}'.format(ftname))
LOG.info('Stopping fabric')
self.fabric.stop()
LOG.info('Stopping mgmtbus')
self.mgmtbus.stop()
LOG.info('chassis - stopped')
self.poweroff.set(value='stop')
def start(self):
LOG.info("chassis start called")
self.log_glet = gevent.spawn(self._log_actor)
self.status_glet = gevent.spawn(self._status_actor)
for ftname, ft in self.fts.iteritems():
LOG.debug("starting %s", ftname)
ft.start()
self.fabric.start_dispatching()
================================================
FILE: minemeld/collectd.py
================================================
# Copyright 2015-2016 Palo Alto Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
minemeld.collectd
Provides a client to collectd for storing metrics.
"""
import socket
import logging
LOG = logging.getLogger(__name__)
class CollectdClient(object):
"""Collectd client.
Args:
path (str): path to the collectd unix socket
"""
def __init__(self, path):
self.path = path
self.socket = None
def _open_socket(self):
if self.socket is not None:
return
_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
_socket.connect(self.path)
self.socket = _socket
def _readline(self):
result = ''
data = None
while data != '\n':
data = self.socket.recv(1)
if data == '\n' or data is None:
return result
result += data
def _send_cmd(self, command):
self._open_socket()
self.socket.send(command+'\n')
ans = self._readline()
status, message = ans.split(None, 1)
status = int(status)
if status < 0:
raise RuntimeError('Error communicating with collectd %s' %
message)
message = [message]
for _ in range(status):
message.append(self._readline())
return status, '\n'.join(message)
def flush(self, identifier=None, timeout=None):
cmd = 'FLUSH'
if timeout is not None:
cmd += ' timeout=%d' % timeout
if identifier is not None:
cmd += ' identifier=%s' % identifier
self._send_cmd(
cmd
)
def putval(self, identifier, value, timestamp='N',
type_='minemeld_counter', hostname='minemeld', interval=None):
if isinstance(timestamp, int):
timestamp = '%d' % timestamp
identifier = '/'.join([hostname, identifier, type_])
command = 'PUTVAL %s' % identifier
if interval is not None:
command += ' interval=%d' % interval
command += ' %s:%d' % (timestamp, value)
self._send_cmd(command)
================================================
FILE: minemeld/comm/__init__.py
================================================
from __future__ import absolute_import
from .zmqredis import ZMQRedis
def factory(commclass, config):
if commclass == 'ZMQRedis':
return ZMQRedis(config)
return ZMQRedis(config)
def cleanup(commclass, config):
return ZMQRedis.cleanup(config)
================================================
FILE: minemeld/comm/zmqredis.py
================================================
# Copyright 2015-2016 Palo Alto Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# disable import error
# pylint:disable=E1101
"""
This module implements ZMQ and Redis communication class for mgmtbus and fabric.
"""
from __future__ import absolute_import
import logging
import uuid
import os
import time
import gevent
import gevent.event
import ujson as json
from errno import EAGAIN
import redis
import zmq.green as zmq
LOG = logging.getLogger(__name__)
class RedisPubChannel(object):
def __init__(self, topic, connection_pool):
self.topic = topic
self.prefix = 'mm:topic:{}'.format(self.topic)
self.connection_pool = connection_pool
self.SR = None
self.num_publish = 0
def connect(self):
if self.SR is not None:
return
self.SR = redis.StrictRedis(
connection_pool=self.connection_pool
)
def disconnect(self):
if self.SR is None:
return
self.SR = None
def lagger(self):
# get status of subscribers
subscribersc = self.SR.lrange(
'{}:subscribers'.format(self.prefix),
0, -1
)
subscribersc = [int(sc) for sc in subscribersc]
# check the lagger
minsubc = self.num_publish
if len(subscribersc) != 0:
minsubc = min(subscribersc)
return minsubc
def gc(self, lagger):
minhighbits = lagger >> 12
minqname = '{}:queue:{:013X}'.format(
self.prefix,
minhighbits
)
# delete all the lists before the lagger
queues = self.SR.keys('{}:queue:*'.format(self.prefix))
LOG.debug('topic {} - queues: {!r}'.format(self.topic, queues))
queues = [q for q in queues if q < minqname]
LOG.debug('topic {} - queues to be deleted: {!r}'.format(self.topic, queues))
if len(queues) != 0:
LOG.debug('topic {} - deleting {!r}'.format(
self.topic,
queues
))
self.SR.delete(*queues)
def publish(self, method, params=None):
high_bits = self.num_publish >> 12
low_bits = self.num_publish & 0xfff
if (low_bits % 128) == 127:
lagger = self.lagger()
LOG.debug('topic {} - sent {} lagger {}'.format(
self.topic,
self.num_publish,
lagger
))
while (self.num_publish - lagger) > 1024:
LOG.debug('topic {} - waiting lagger delta: {}'.format(
self.topic,
self.num_publish - lagger
))
gevent.sleep(0.1)
lagger = self.lagger()
if low_bits == 0xfff:
# we are switching to a new list, gc
self.gc(lagger)
msg = {
'method': method,
'params': params
}
qname = '{}:queue:{:013X}'.format(
self.prefix,
high_bits
)
self.SR.rpush(qname, json.dumps(msg))
self.num_publish += 1
class ZMQRpcFanoutClientChannel(object):
def __init__(self, fanout):
self.socket = None
self.reply_socket = None
self.context = None
self.fanout = fanout
self.active_rpcs = {}
def run(self):
while True:
LOG.debug('RPC Fanout reply recving from {}:reply'.format(self.fanout))
body = self.reply_socket.recv_json()
LOG.debug('RPC Fanout reply from {}:reply recvd: {!r}'.format(self.fanout, body))
self.reply_socket.send('OK')
LOG.debug('RPC Fanout reply from {}:reply recvd: {!r} - ok'.format(self.fanout, body))
source = body.get('source', None)
if source is None:
LOG.error('No source in reply in ZMQRpcFanoutClientChannel {}'.format(self.fanout))
continue
id_ = body.get('id', None)
if id_ is None:
LOG.error('No id in reply in ZMQRpcFanoutClientChannel {} from {}'.format(self.fanout, source))
continue
actreq = self.active_rpcs.get(id_, None)
if actreq is None:
LOG.error('Unknown id {} in reply in ZMQRpcFanoutClientChannel {} from {}'.format(id_, self.fanout, source))
continue
result = body.get('result', None)
if result is None:
actreq['errors'] += 1
errmsg = body.get('error', 'no error in reply')
LOG.error('Error in RPC reply from {}: {}'.format(source, errmsg))
else:
actreq['answers'][source] = result
LOG.debug('RPC Fanout state: {!r}'.format(actreq))
if len(actreq['answers'])+actreq['errors'] >= actreq['num_results']:
actreq['event'].set({
'answers': actreq['answers'],
'errors': actreq['errors']
})
self.active_rpcs.pop(id_)
gevent.sleep(0)
def send_rpc(self, method, params=None, num_results=0, and_discard=False):
if self.socket is None:
raise RuntimeError('Not connected')
if params is None:
params = {}
id_ = str(uuid.uuid1())
body = {
'reply_to': '{}:reply'.format(self.fanout),
'method': method,
'id': id_,
'params': params
}
event = gevent.event.AsyncResult()
if num_results == 0:
event.set({
'answers': {},
'errors': 0
})
return event
self.active_rpcs[id_] = {
'cmd': method,
'answers': {},
'num_results': num_results,
'event': event,
'errors': 0,
'discard': and_discard
}
LOG.debug('RPC Fanout Client: send multipart to {}: {!r}'.format(self.fanout, json.dumps(body)))
self.socket.send_multipart([
'{}'.format(self.fanout),
json.dumps(body)
])
LOG.debug('RPC Fanout Client: send multipart to {}: {!r} - done'.format(self.fanout, json.dumps(body)))
gevent.sleep(0)
return event
def connect(self, context):
if self.socket is not None:
return
self.context = context
self.socket = context.socket(zmq.PUB)
self.socket.bind('ipc:///var/run/minemeld/{}'.format(self.fanout))
self.reply_socket = context.socket(zmq.REP)
self.reply_socket.bind('ipc:///var/run/minemeld/{}:reply'.format(self.fanout))
def disconnect(self):
if self.socket is None:
return
self.socket.close(linger=0)
self.reply_socket.close(linger=0)
self.socket = None
self.reply_socket = None
class ZMQRpcServerChannel(object):
def __init__(self, name, obj, allowed_methods=None,
method_prefix='', fanout=None):
if allowed_methods is None:
allowed_methods = []
self.name = name
self.obj = obj
self.allowed_methods = allowed_methods
self.method_prefix = method_prefix
self.fanout = fanout
self.context = None
self.socket = None
def _send_result(self, reply_to, id_, result=None, error=None):
ans = {
'source': self.name,
'id': id_,
'result': result,
'error': error
}
if self.fanout is not None:
reply_socket = self.context.socket(zmq.REQ)
reply_socket.connect('ipc:///var/run/minemeld/{}'.format(reply_to))
LOG.debug('RPC Server {} result to {}'.format(self.name, reply_to))
reply_socket.send_json(ans)
reply_socket.recv()
LOG.debug('RPC Server {} result to {} - done'.format(self.name, reply_to))
reply_socket.close(linger=0)
LOG.debug('RPC Server {} result to {} - closed'.format(self.name, reply_to))
reply_socket = None
else:
self.socket.send_multipart([reply_to, '', json.dumps(ans)])
def run(self):
if self.socket is None:
LOG.error('Run called with invalid socket in RPC server channel: {}'.format(self.name))
while True:
LOG.debug('RPC Server receiving from {} - {}'.format(self.name, self.fanout))
toks = self.socket.recv_multipart()
LOG.debug('RPC Server recvd from {} - {}: {!r}'.format(self.name, self.fanout, toks))
if self.fanout is not None:
reply_to, body = toks
reply_to = reply_to+':reply'
else:
reply_to, _, body = toks
body = json.loads(body)
LOG.debug('RPC command to {}: {!r}'.format(self.name, body))
method = body.get('method', None)
id_ = body.get('id', None)
params = body.get('params', {})
if method is None:
LOG.error('No method in msg body')
return
if id_ is None:
LOG.error('No id in msg body')
return
method = self.method_prefix+method
if method not in self.allowed_methods:
LOG.error('Method not allowed in RPC server channel {}: {}'.format(self.name, method))
self._send_result(reply_to, id_, error='Method not allowed')
m = getattr(self.obj, method, None)
if m is None:
LOG.error('Method {} not defined in RPC server channel {}'.format(method, self.name))
self._send_result(reply_to, id_, error='Method not defined')
try:
result = m(**params)
except gevent.GreenletExit:
raise
except Exception as e:
self._send_result(reply_to, id_, error=str(e))
else:
self._send_result(reply_to, id_, result=result)
def connect(self, context):
if self.socket is not None:
return
self.context = context
if self.fanout is not None:
# we are subscribers
self.socket = self.context.socket(zmq.SUB)
self.socket.connect('ipc:///var/run/minemeld/{}'.format(self.fanout))
self.socket.setsockopt(zmq.SUBSCRIBE, b'') # set the filter to empty to recv all messages
else:
# we are a router
self.socket = self.context.socket(zmq.ROUTER)
if self.name[0] == '@':
address = 'ipc://@/var/run/minemeld/{}:rpc'.format(
self.name[1:]
)
else:
address = 'ipc:///var/run/minemeld/{}:rpc'.format(
self.name
)
self.socket.bind(address)
def disconnect(self):
if self.socket is not None:
self.socket.close(linger=0)
self.socket = None
class ZMQPubChannel(object):
def __init__(self, topic):
self.socket = None
self.reply_socket = None
self.context = None
self.topic = topic
def publish(self, method, params=None):
if self.socket is None:
raise RuntimeError('Not connected')
if params is None:
params = {}
id_ = str(uuid.uuid1())
body = {
'method': method,
'id': id_,
'params': params
}
try:
self.socket.send_json(
obj=body,
flags=zmq.NOBLOCK
)
except zmq.ZMQError:
LOG.error('Topic {} queue full - dropping message'.format(self.topic))
gevent.sleep(0)
def connect(self, context):
if self.socket is not None:
return
self.context = context
self.socket = context.socket(zmq.PUB)
self.socket.bind('ipc:///var/run/minemeld/{}'.format(self.topic))
def disconnect(self):
if self.socket is None:
return
self.socket.close(linger=0)
self.socket = None
class ZMQSubChannel(object):
def __init__(self, name, obj, allowed_methods=None,
method_prefix='', topic=None):
if allowed_methods is None:
allowed_methods = []
self.name = name
self.obj = obj
self.allowed_methods = allowed_methods
self.method_prefix = method_prefix
self.topic = topic
self.context = None
self.socket = None
def run(self):
if self.socket is None:
LOG.error('Run called with invalid socket in ZMQ Pub channel: {}'.format(self.name))
while True:
LOG.debug('ZMQPub {} receiving'.format(self.name))
body = self.socket.recv_json()
LOG.debug('ZMQPub {} recvd: {!r}'.format(self.name, body))
method = body.get('method', None)
id_ = body.get('id', None)
params = body.get('params', {})
if method is None:
LOG.error('No method in msg body')
return
if id_ is None:
LOG.error('No id in msg body')
return
method = self.method_prefix+method
if method not in self.allowed_methods:
LOG.error('Method not allowed in RPC server channel {}: {}'.format(self.name, method))
continue
m = getattr(self.obj, method, None)
if m is None:
LOG.error('Method {} not defined in RPC server channel {}'.format(method, self.name))
continue
try:
m(**params)
except gevent.GreenletExit:
raise
except Exception:
LOG.exception('Exception in ZMQPub {}'.format(self.name))
def connect(self, context):
if self.socket is not None:
return
self.context = context
self.socket = self.context.socket(zmq.SUB)
self.socket.connect('ipc:///var/run/minemeld/{}'.format(self.topic))
self.socket.setsockopt(zmq.SUBSCRIBE, b'') # set the filter to empty to recv all messages
def disconnect(self):
if self.socket is not None:
self.socket.close(linger=0)
self.socket = None
class RedisSubChannel(object):
def __init__(self, topic, connection_pool, object_,
allowed_methods, name=None):
self.topic = topic
self.prefix = 'mm:topic:{}'.format(self.topic)
self.channel = None
self.name = name
self.object = object_
self.allowed_methods = allowed_methods
self.connection_pool = connection_pool
self.num_callbacks = 0
self.sub_number = None
def _callback(self, msg):
try:
msg = json.loads(msg)
except ValueError:
LOG.error("invalid message received")
return
method = msg.get('method', None)
params = msg.get('params', {})
if method is None:
LOG.error("Message without method field")
return
if method not in self.allowed_methods:
LOG.error("Method not allowed: %s", method)
return
m = getattr(self.object, method, None)
if m is None:
LOG.error('Method %s not defined', method)
return
try:
m(**params)
except gevent.GreenletExit:
raise
except:
LOG.exception('Exception in handling %s on topic %s '
'with params %s', method, self.topic, params)
self.num_callbacks += 1
def connect(self):
subscribers_key = '{}:subscribers'.format(self.prefix)
SR = redis.StrictRedis(
connection_pool=self.connection_pool
)
self.sub_number = SR.rpush(
subscribers_key,
0
)
self.sub_number -= 1
LOG.debug('Sub Number {} on {}'.format(self.sub_number, subscribers_key))
def disconnect(self):
pass
class ZMQRedis(object):
def __init__(self, config):
self.context = None
self.rpc_server_channels = {}
self.pub_channels = []
self.mw_pub_channels = []
self.sub_channels = []
self.mw_sub_channels = []
self.rpc_fanout_clients_channels = []
self.active_rpcs = {}
self.ioloops = []
self.failure_listeners = []
self.redis_config = {
'url': os.environ.get('REDIS_URL', 'unix:///var/run/redis/redis.sock')
}
self.redis_cp = redis.ConnectionPool.from_url(
self.redis_config['url']
)
def add_failure_listener(self, listener):
self.failure_listeners.append(listener)
def request_rpc_server_channel(self, name, obj=None, allowed_methods=None,
method_prefix='', fanout=None):
if allowed_methods is None:
allowed_methods = []
if name in self.rpc_server_channels:
return
self.rpc_server_channels[name] = ZMQRpcServerChannel(
name,
obj,
method_prefix=method_prefix,
allowed_methods=allowed_methods,
fanout=fanout
)
def request_rpc_fanout_client_channel(self, topic):
c = ZMQRpcFanoutClientChannel(topic)
self.rpc_fanout_clients_channels.append(c)
return c
def request_pub_channel(self, topic, multi_write=False):
if not multi_write:
redis_pub_channel = RedisPubChannel(
topic=topic,
connection_pool=self.redis_cp
)
self.pub_channels.append(redis_pub_channel)
return redis_pub_channel
zmq_pub_channel = ZMQPubChannel(topic=topic)
self.mw_pub_channels.append(zmq_pub_channel)
return zmq_pub_channel
def request_sub_channel(self, topic, obj=None, allowed_methods=None,
name=None, max_length=None, multi_write=False):
if allowed_methods is None:
allowed_methods = []
if not multi_write:
subchannel = RedisSubChannel(
topic=topic,
connection_pool=self.redis_cp,
object_=obj,
allowed_methods=allowed_methods,
name=name
)
self.sub_channels.append(subchannel)
return
subchannel = ZMQSubChannel(
name=name,
obj=obj,
allowed_methods=allowed_methods,
topic=topic
)
self.mw_sub_channels.append(subchannel)
def send_rpc(self, dest, method, params,
block=True, timeout=None):
if self.context is None:
LOG.error('send_rpc to {} when not connected'.format(dest))
return
id_ = str(uuid.uuid1())
body = {
'method': method,
'id': id_,
'params': params
}
socket = self.context.socket(zmq.REQ)
if dest[0] == '@':
address = 'ipc://@/var/run/minemeld/{}:rpc'.format(
dest[1:]
)
else:
address = 'ipc:///var/run/minemeld/{}:rpc'.format(
dest
)
socket.connect(address)
socket.setsockopt(zmq.LINGER, 0)
socket.send_json(body)
LOG.debug('RPC sent to {}:rpc for method {}'.format(dest, method))
if not block:
socket.close(linger=0)
return
if timeout is not None:
# zmq green does not support RCVTIMEO
if socket.poll(flags=zmq.POLLIN, timeout=int(timeout*1000)) != 0:
result = socket.recv_json(flags=zmq.NOBLOCK)
else:
socket.close(linger=0)
raise RuntimeError('Timeout in RPC')
else:
result = socket.recv_json()
socket.close(linger=0)
return result
def _ioloop(self, executor):
executor.run()
def _sub_ioloop(self, schannel):
LOG.debug('start draining messages on topic {}'.format(schannel.topic))
counter = 0
SR = redis.StrictRedis(connection_pool=self.redis_cp)
subscribers_key = '{}:subscribers'.format(schannel.prefix)
while True:
base = counter & 0xfff
top = min(base + 127, 0xfff)
msgs = SR.lrange(
'{}:queue:{:013X}'.format(schannel.prefix, counter >> 12),
base,
top
)
for m in msgs:
LOG.debug('topic {} - {!r}'.format(
schannel.topic,
m
))
schannel._callback(m)
counter += len(msgs)
if len(msgs) > 0:
SR.lset(
subscribers_key,
schannel.sub_number,
counter
)
if len(msgs) < (top - base + 1):
gevent.sleep(1.0)
else:
gevent.sleep(0)
def _ioloop_failure(self, g):
LOG.error('_ioloop_failure')
try:
g.get()
except gevent.GreenletExit:
return
except:
LOG.exception("_ioloop_failure: exception in ioloop")
for l in self.failure_listeners:
l()
def start(self, start_dispatching=True):
self.context = zmq.Context()
for rfcc in self.rpc_fanout_clients_channels:
rfcc.connect(self.context)
for rpcc in self.rpc_server_channels.values():
rpcc.connect(self.context)
for sc in self.sub_channels:
sc.connect()
for mwsc in self.mw_sub_channels:
mwsc.connect(self.context)
for pc in self.pub_channels:
pc.connect()
for mwpc in self.mw_pub_channels:
mwpc.connect(self.context)
if start_dispatching:
self.start_dispatching()
def start_dispatching(self):
for rfcc in self.rpc_fanout_clients_channels:
g = gevent.spawn(self._ioloop, rfcc)
self.ioloops.append(g)
g.link_exception(self._ioloop_failure)
for rpcc in self.rpc_server_channels.values():
g = gevent.spawn(self._ioloop, rpcc)
self.ioloops.append(g)
g.link_exception(self._ioloop_failure)
for schannel in self.sub_channels:
g = gevent.spawn(self._sub_ioloop, schannel)
self.ioloops.append(g)
g.link_exception(self._ioloop_failure)
for mwschannel in self.mw_sub_channels:
g = gevent.spawn(self._ioloop, mwschannel)
self.ioloops.append(g)
g.link_exception(self._ioloop_failure)
def stop(self):
# kill ioloops
for j in xrange(len(self.ioloops)):
self.ioloops[j].unlink(self._ioloop_failure)
self.ioloops[j].kill()
self.ioloops[j] = None
self.ioloops = None
# close channels
for rpcc in self.rpc_server_channels.values():
try:
rpcc.disconnect()
except Exception:
LOG.debug("exception in disconnect: ", exc_info=True)
for pc in self.pub_channels:
try:
pc.disconnect()
except Exception:
LOG.debug("exception in disconnect: ", exc_info=True)
for mwpc in self.mw_pub_channels:
try:
mwpc.disconnect()
except Exception:
LOG.debug("exception in disconnect: ", exc_info=True)
for sc in self.sub_channels:
try:
sc.disconnect()
except Exception:
LOG.debug("exception in disconnect: ", exc_info=True)
for mwsc in self.mw_sub_channels:
try:
mwsc.disconnect()
except Exception:
LOG.debug("exception in disconnect: ", exc_info=True)
for rfc in self.rpc_fanout_clients_channels:
try:
rfc.disconnect()
except Exception:
LOG.debug("exception in disconnect: ", exc_info=True)
self.context.destroy()
@staticmethod
def cleanup(config):
redis_cp = redis.ConnectionPool.from_url(
os.environ.get('REDIS_URL', 'unix:///var/run/redis/redis.sock')
)
SR = redis.StrictRedis(connection_pool=redis_cp)
tkeys = SR.keys(pattern='mm:topic:*')
if len(tkeys) > 0:
LOG.info('Deleting old keys: {}'.format(len(tkeys)))
SR.delete(*tkeys)
SR = None
redis_cp = None
================================================
FILE: minemeld/extensions/__init__.py
================================================
from .manager import * # noqa
================================================
FILE: minemeld/extensions/manager.py
================================================
import sys
import os
import os.path
import json
import logging
from email.parser import Parser
from collections import namedtuple
from zipfile import ZipFile
from pkg_resources import EntryPoint, parse_version
import minemeld.loader
LOG = logging.getLogger(__name__)
__all__ = [
'get_metadata_from_wheel',
'activated_extensions',
'installed_extensions',
'extensions',
'freeze',
'load_frozen_paths'
]
METADATA_MAP = {
'name': 'Name',
'version': 'Version',
'author': 'Author',
'author_email': 'Author-email',
'description': 'Summary',
'url': 'Home-page'
}
InstalledExtension = namedtuple(
'InstalledExtension',
[
'name', 'version', 'author', 'author_email',
'description', 'url', 'path', 'entry_points'
]
)
ActivatedExtension = namedtuple(
'ActivatedExtension',
[
'name', 'version', 'author', 'author_email',
'description', 'url', 'location', 'entry_points'
]
)
ExternalExtension = namedtuple(
'ExternalExtension',
[
'name', 'version', 'author', 'author_email',
'description', 'url', 'path', 'activated',
'installed', 'entry_points'
]
)
def _egg_link_path(dist):
for path_item in sys.path:
egg_link = os.path.join(path_item, dist.project_name + '.egg-link')
if os.path.isfile(egg_link):
return egg_link
return None
def _read_metadata(metadata_str):
return Parser().parsestr(metadata_str)
def _read_entry_points(ep_contents):
ep_map = EntryPoint.parse_map(ep_contents)
for _, epgroup in ep_map.iteritems():
for epname, ep in epgroup.iteritems():
epgroup[epname] = str(ep)
return ep_map
def _activated_extensions():
epgroups = (
minemeld.loader.MM_NODES_ENTRYPOINT,
minemeld.loader.MM_NODES_GCS_ENTRYPOINT,
minemeld.loader.MM_NODES_VALIDATORS_ENTRYPOINT,
minemeld.loader.MM_PROTOTYPES_ENTRYPOINT,
minemeld.loader.MM_API_ENTRYPOINT,
minemeld.loader.MM_WEBUI_ENTRYPOINT
)
activated_extensions = {}
for epgroup in epgroups:
for _, epvalue in minemeld.loader.map(epgroup).iteritems():
if epvalue.ep.dist.project_name == 'minemeld-core':
continue
location = 'site-packages'
egg_link = _egg_link_path(epvalue.ep.dist)
if egg_link is not None:
with open(egg_link, 'r') as f:
location = f.readline().strip()
metadata = {
'name': epvalue.ep.dist.project_name,
'version': epvalue.ep.dist.version,
'author': None,
'author_email': None,
'description': None,
'url': None,
'entry_points': None
}
if egg_link:
try:
with open(os.path.join(location, 'minemeld.json'), 'r') as f:
dist_metadata = json.load(f)
for k in metadata.keys():
metadata[k] = dist_metadata.get(k, None)
except (IOError, OSError) as excpt:
LOG.error('Error loading metatdata from {}: {}'.format(location, str(excpt)))
elif epvalue.ep.dist.has_metadata('METADATA'):
dist_metadata = _read_metadata(
epvalue.ep.dist.get_metadata('METADATA')
)
for k in metadata.keys():
if k in METADATA_MAP and METADATA_MAP[k] in dist_metadata:
metadata[k] = dist_metadata[METADATA_MAP[k]]
if epvalue.ep.dist.has_metadata('entry_points.txt'):
metadata['entry_points'] = _read_entry_points(
epvalue.ep.dist.get_metadata('entry_points.txt')
)
activated_extensions[epvalue.ep.dist.project_name] = ActivatedExtension(
location=location,
**metadata
)
return activated_extensions
def _load_metadata_from_wheel(extpath, extname=None):
wheel_name = extname
if extname is None:
wheel_name = os.path.basename(extpath)
project_name, version, _ = wheel_name.split('-', 2)
metadata_path = '{}-{}.dist-info/METADATA'.format(project_name, version)
with ZipFile(extpath, 'r') as wheel_file:
metadata_file = wheel_file.open(metadata_path, 'r')
metadata_lines = metadata_file.read()
metadata = _read_metadata(metadata_lines)
# classifier framework :: minemeld should be in METADATA
# for this to be an extension
classifiers = metadata.get_all('Classifier')
if classifiers is None:
return None
for c in classifiers:
if c.lower() == 'framework :: minemeld':
break
else:
return None
ie_metadata = {}
for field in InstalledExtension._fields:
if field == 'path' or field == 'entry_points':
continue
ie_metadata[field] = metadata.get(METADATA_MAP[field], None)
entry_points = None
try:
ep_path = '{}-{}.dist-info/entry_points.txt'.format(project_name, version)
with ZipFile(extpath, 'r') as wheel_file:
ep_file = wheel_file.open(ep_path, 'r')
ep_contents = ep_file.read()
entry_points = _read_entry_points(ep_contents)
except (IOError, OSError):
pass
ie_metadata['entry_points'] = entry_points
return InstalledExtension(
path=extpath,
**ie_metadata
)
def _load_metadata_from_dir(extpath):
with open(os.path.join(extpath, 'minemeld.json'), 'r') as f:
metadata = json.load(f)
return InstalledExtension(
name=metadata['name'],
version=metadata['version'],
author=metadata['author'],
author_email=metadata.get('author_email', None),
description=metadata.get('description', None),
url=metadata.get('url', None),
entry_points=metadata.get('entry_points', None),
path=extpath
)
def _is_activated(installed_extension, activated):
activated_extension = activated.get(installed_extension.name, None)
if activated_extension is None:
return False
if activated_extension.version != installed_extension.version:
return False
if installed_extension.path == activated_extension.location:
return True
if activated_extension.location == 'site-packages' and \
installed_extension.path.endswith('.whl'):
return True
return False
def get_metadata_from_wheel(wheelpath, wheelname=None):
return _load_metadata_from_wheel(wheelpath, wheelname)
def installed_extensions(installation_dir):
_installed_extensions = []
entries = os.listdir(installation_dir)
for e in entries:
epath = os.path.join(installation_dir, e)
# check if this is a wheel
if e.endswith('.whl'):
try:
installed_extension = _load_metadata_from_wheel(epath)
if installed_extension is None:
continue
_installed_extensions.append(installed_extension)
except (ValueError, IOError, KeyError, OSError) as excpt:
LOG.error(u'Error extracting metadata from {}: {}'.format(e, str(excpt)))
# check if it is a directory
elif os.path.isdir(epath):
try:
installed_extension = _load_metadata_from_dir(epath)
if installed_extension is None:
continue
_installed_extensions.append(installed_extension)
except (IOError, OSError, KeyError) as excpt:
LOG.error(u'Error extracting metadata from {}: {}'.format(e, str(excpt)))
return _installed_extensions
def activated_extensions():
return _activated_extensions()
def extensions(installation_dir):
_extensions = []
_installed = installed_extensions(installation_dir)
_activated = activated_extensions()
for installed_extension in _installed:
_extension_activated = _is_activated(installed_extension, _activated)
_extensions.append(ExternalExtension(
installed=True,
activated=_extension_activated,
**installed_extension._asdict()
))
if _extension_activated:
_activated.pop(installed_extension.name)
for _activated_extension in _activated.values():
_adict = _activated_extension._asdict()
_adict.pop('location')
_extensions.append(ExternalExtension(
installed=False,
activated=True,
path=None,
**_adict
))
return _extensions
def freeze(installation_dir):
_freeze = []
_extensions = extensions(installation_dir)
for e in _extensions:
if not e.activated:
continue
if not e.installed:
continue
if e.path.endswith('.whl'):
_freeze.append(e.path)
else:
_freeze.append('-e {}'.format(e.path))
return _freeze
def load_frozen_paths(freeze_file):
for l in freeze_file:
l = l.strip()
if not l.startswith('-e '):
continue
_, epath = l.split(' ', 1)
if epath not in sys.path:
LOG.info('Extension path {!r} not in sys.path, adding'.format(epath))
sys.path.append(epath)
================================================
FILE: minemeld/fabric.py
================================================
# Copyright 2015-2016 Palo Alto Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
minemeld.fabric
This module implements fabric abstraction over communication backend class.
Each chassis has an instance of Fabric and nodes request connections to the
fabric using this instance.
"""
from __future__ import absolute_import
import logging
import minemeld.comm
LOG = logging.getLogger(__name__)
class Fabric(object):
"""MineMeld chassis fabric class
Args:
chassis: MineMeld chassis instance
config (dict): communication backend config
comm_class (string): communication backend to be used
"""
def __init__(self, chassis, config, comm_class):
self.chassis = chassis
self.comm_config = config
self.comm_class = comm_class
self.comm = minemeld.comm.factory(self.comm_class, self.comm_config)
def request_rpc_channel(self, ftname, node, allowed_methods):
"""Creates a new RPC channel on the communication backend.
Args:
ftname (str): node name
node: node instance
allowed_methods (list): list of allowed methods
"""
self.comm.request_rpc_server_channel(ftname, node, allowed_methods)
def request_pub_channel(self, ftname):
"""Creates a new channel for publishing to a topic with name ftname.
Args:
ftname (str): node name
"""
return self.comm.request_pub_channel(ftname)
def request_sub_channel(self, ftname, node, subname, allowed_methods):
"""Creates a subscription channel to topic subname.
Args:
ftname (str): name of the node
node: node instance
subname (str): name of the topic to subscribe to
allowed_methods (list): list of allowed methods
"""
_ = ftname # noqa
self.comm.request_sub_channel(subname, node, allowed_methods)
def send_rpc(self, sftname, dftname, method, params,
block=True, timeout=None):
"""Sends a RPC command to a specific node.
Args:
sftname (str): source node name
dftname (str): destination node name
method (str): method name
params (dict): parameters
block (bool): if call should block
timeout (int): timeout in seconds
"""
params['source'] = sftname
self.comm.send_rpc(
dftname,
method,
params,
block=block,
timeout=timeout
)
def _comm_failure(self):
self.chassis.fabric_failed()
def start(self):
LOG.debug("fabric start called")
self.comm.add_failure_listener(self._comm_failure)
self.comm.start(start_dispatching=False)
def start_dispatching(self):
self.comm.start_dispatching()
def stop(self):
LOG.debug("fabric stop called")
self.comm.stop()
def factory(classname, chassis, config):
"""Factory for Fabric class.
Args:
classname (str): communication backend name
chassis: chassis instance
config (dict): communication backend config
"""
return Fabric(
chassis=chassis,
config=config,
comm_class=classname
)
================================================
FILE: minemeld/flask/__init__.py
================================================
# Copyright 2015 Palo Alto Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import logging
import yaml
from flask import Flask
import minemeld.loader
from .logger import LOG
REDIS_URL = os.environ.get('REDIS_URL', 'unix:///var/run/redis/redis.sock')
def create_app():
yaml.SafeLoader.add_constructor(
u'tag:yaml.org,2002:timestamp',
yaml.SafeLoader.construct_yaml_str
)
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024 # max 5MB for uploads
LOG.init_app(app)
# extension code
from . import config
from . import aaa
from . import session
from . import mmrpc
from . import redisclient
from . import supervisorclient
from . import jobs
from . import sns
from . import events
session.init_app(app, REDIS_URL)
aaa.init_app(app)
config.init()
if config.get('DEBUG', False):
logging.getLogger().setLevel(logging.DEBUG)
else:
logging.getLogger().setLevel(logging.INFO)
mmrpc.init_app(app)
redisclient.init_app(app)
supervisorclient.init_app(app)
jobs.init_app(app)
sns.init_app()
events.init_app(app, REDIS_URL)
# entrypoints
from . import metricsapi # noqa
from . import feedredis # noqa
from . import configapi # noqa
from . import configdataapi # noqa
from . import taxiidiscovery # noqa
from . import taxiicollmgmt # noqa
from . import taxiipoll # noqa
from . import supervisorapi # noqa
from . import loginapi # noqa
from . import prototypeapi # noqa
from . import validateapi # noqa
from . import aaaapi # noqa
from . import statusapi # noqa
from . import tracedapi # noqa
from . import logsapi # noqa
from . import extensionsapi # noqa
from . import jobsapi # noqa
configapi.init_app(app)
extensionsapi.init_app(app)
app.register_blueprint(metricsapi.BLUEPRINT)
app.register_blueprint(statusapi.BLUEPRINT)
app.register_blueprint(feedredis.BLUEPRINT)
app.register_blueprint(configapi.BLUEPRINT)
app.register_blueprint(configdataapi.BLUEPRINT)
app.register_blueprint(taxiidiscovery.BLUEPRINT)
app.register_blueprint(taxiicollmgmt.BLUEPRINT)
app.register_blueprint(taxiipoll.BLUEPRINT)
app.register_blueprint(supervisorapi.BLUEPRINT)
app.register_blueprint(loginapi.BLUEPRINT)
app.register_blueprint(prototypeapi.BLUEPRINT)
app.register_blueprint(validateapi.BLUEPRINT)
app.register_blueprint(aaaapi.BLUEPRINT)
app.register_blueprint(tracedapi.BLUEPRINT)
app.register_blueprint(logsapi.BLUEPRINT)
app.register_blueprint(extensionsapi.BLUEPRINT)
app.register_blueprint(jobsapi.BLUEPRINT)
# install blueprints from extensions
for apiname, apimmep in minemeld.loader.map(minemeld.loader.MM_API_ENTRYPOINT).iteritems():
LOG.info('Loading blueprint from {}'.format(apiname))
if not apimmep.loadable:
LOG.info('API entrypoint {} not loadable, ignored'.format(apiname))
continue
try:
bprint = apimmep.ep.load()
app.register_blueprint(bprint())
except (ImportError, RuntimeError):
LOG.exception('Error loading API entry point {}'.format(apiname))
# install webui blueprints from extensions
for webuiname, webuimmep in minemeld.loader.map(minemeld.loader.MM_WEBUI_ENTRYPOINT).iteritems():
LOG.info('Loading blueprint from {}'.format(webuiname))
if not webuimmep.loadable:
LOG.info('API entrypoint {} not loadable, ignored'.format(webuiname))
continue
try:
bprint = webuimmep.ep.load()
app.register_blueprint(
bprint(),
url_prefix='/extensions/webui/{}'.format(webuiname)
)
except (ImportError, RuntimeError):
LOG.exception('Error loading WebUI entry point {}'.format(webuiname))
for r in app.url_map.iter_rules():
LOG.debug('app rule: {!r}'.format(r))
return app
================================================
FILE: minemeld/flask/aaa.py
================================================
# Copyright 2015-2016 Palo Alto Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import base64
from functools import wraps
import gevent
import gevent.lock
import flask.ext.login
from flask import current_app, Blueprint, request
from . import config
from .logger import LOG
ANONYMOUS = 'mm-anonymous'
PREVENT_WRITE_GUARD = None
PREVENT_WRITE = None
def disable_prevent_write(locker):
global PREVENT_WRITE
with PREVENT_WRITE_GUARD:
if PREVENT_WRITE == locker:
LOG.info('Disabled prevent write from locker {}'.format(locker))
PREVENT_WRITE = None
def enable_prevent_write(locker, timeout=900):
global PREVENT_WRITE
def _cleanup_prevent_write():
gevent.sleep(timeout)
LOG.info('Checking if prevent write still enabled by locker {}'.format(locker))
disable_prevent_write(locker)
with PREVENT_WRITE_GUARD:
if PREVENT_WRITE is None:
PREVENT_WRITE = locker
gevent.spawn(_cleanup_prevent_write)
return False
class MMBlueprint(Blueprint):
def __init__(self, *args, **kwargs):
super(MMBlueprint, self).__init__(*args, **kwargs)
self.send_static_file = self._login_required(
super(MMBlueprint, self).send_static_file,
login_required=True,
read_write=False,
feeds=False
)
def _audit(self, f, audit_required):
if not audit_required:
return f
@wraps(f)
def audited_view(*args, **kwargs):
if request and flask.ext.login.current_user:
params = []
for key, values in request.values.iterlists():
if key == '_':
continue
params.append(('value:{}'.format(key), values))
for filename, files in request.files.iterlists():
params.append(('file:{}'.format(filename), [file.filename for file in files]))
body = request.get_json(silent=True)
if body is not None:
params.append(['jsonbody', json.dumps(body)[:1024]])
LOG.audit(
user_id=flask.ext.login.current_user.get_id(),
action_name='{} {}'.format(request.method, request.path),
params=params
)
else:
LOG.critical('no request or current_user in audited_view')
return f(*args, **kwargs)
return audited_view
def _login_required(self, f, login_required, read_write, feeds):
@wraps(f)
def decorated_view(*args, **kwargs):
if not login_required:
return f(*args, **kwargs)
if not config.get('API_AUTH_ENABLED', True) and not feeds:
return f(*args, **kwargs)
if not config.get('FEEDS_AUTH_ENABLED', False) and feeds:
return f(*args, **kwargs)
if not feeds:
if not flask.ext.login.current_user.is_authenticated():
return current_app.login_manager.unauthorized()
if flask.ext.login.current_user.get_id().startswith('feeds/'):
return current_app.login_manager.unauthorized()
if read_write and not flask.ext.login.current_user.is_read_write():
return 'Forbidden', 403
return f(*args, **kwargs)
return decorated_view
def _write_prevented(self, f, read_write):
@wraps(f)
def decorated_view(*args, **kwargs):
if read_write and PREVENT_WRITE is not None:
return 'Changes disabled by {}'.format(PREVENT_WRITE), 403
return f(*args, **kwargs)
return decorated_view
def route(self, rule, **options):
def decorator(f):
login_required = options.pop('login_required', True)
read_write = options.pop('read_write', True)
feeds = options.pop("feeds", False)
super_decorator = super(MMBlueprint, self).route(rule, **options)
_wp_f = self._write_prevented(f, read_write)
_lr_f = self._login_required(_wp_f, login_required, read_write, feeds)
_audit_f = self._audit(_lr_f, read_write)
return super_decorator(_audit_f)
return decorator
class MMAnonynmousUser(object):
def __init__(self):
self._id = ANONYMOUS
def get_id(self):
return self._id
def is_authenticated(self):
return False
def is_active(self):
return True
def is_anonymous(self):
return True
def is_read_write(self):
return False
def check_feed(self, feedname):
if not config.get('FEEDS_AUTH_ENABLED', False):
return True
fattributes = config.get('FEEDS_ATTRS', None)
if fattributes is None or feedname not in fattributes:
return False
ftags = set(fattributes[feedname].get('tags', []))
if 'anonymous' in ftags:
return True
return False
class MMAuthenticatedUser(object):
def __init__(self, _id=None):
self._id = unicode(_id)
def get_id(self):
return self._id
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
class MMAuthenticatedAdminUser(MMAuthenticatedUser):
def __init__(self, _id):
super(MMAuthenticatedAdminUser, self).__init__(_id=u'admin/{}'.format(_id))
def is_read_write(self):
read_write = config.get('READ_WRITE', None)
if read_write is None:
return True
if isinstance(read_write, str) or isinstance(read_write, unicode):
read_write = read_write.split(',')
elif not isinstance(read_write, list):
LOG.error('Unknown READ_WRITE format')
return False
if self._id[6:] in read_write:
return True
return False
def check_feed(self, feedname):
return True
class MMAuthenticatedFeedUser(MMAuthenticatedUser):
def __init__(self, _id):
super(MMAuthenticatedFeedUser, self).__init__(_id=u'feeds/{}'.format(_id))
def is_read_write(self):
# this should never be called
return False
def check_feed(self, feedname):
if not config.get('FEEDS_AUTH_ENABLED', False):
return True
fattributes = config.get('FEEDS_ATTRS', None)
if fattributes is None or feedname not in fattributes:
return False
ftags = set(fattributes[feedname].get('tags', []))
# if 'any' is present, any authenticated user can access
# the feed
if 'any' in ftags:
return True
uattributes = config.get('FEEDS_USERS_ATTRS', None)
if uattributes is None or self._id[6:] not in uattributes:
return False
tags = set(uattributes[self._id[6:]].get('tags', []))
return len(tags.intersection(ftags)) != 0
def authenticated_user_factory(_id):
if _id.startswith('feeds/'):
return MMAuthenticatedFeedUser(_id=_id[6:])
if _id.startswith('admin/'):
return MMAuthenticatedAdminUser(_id=_id[6:])
if _id == ANONYMOUS:
return MMAnonynmousUser()
raise RuntimeError('Unknown user_id prefix: {}'.format(_id))
LOGIN_MANAGER = flask.ext.login.LoginManager()
LOGIN_MANAGER.session_protection = None
LOGIN_MANAGER.anonymous_user = MMAnonynmousUser
@LOGIN_MANAGER.request_loader
def request_loader(request):
api_key = request.headers.get('Authorization')
if api_key is None:
return None
api_key = api_key.replace('Basic', '', 1)
try:
api_key = base64.b64decode(api_key)
except TypeError:
return None
try:
user, password = api_key.split(':', 1)
except ValueError:
return None
auth_user = check_feeds_user(user, password)
if auth_user is not None:
return auth_user
auth_user = check_admin_user(user, password)
if auth_user is not None:
return auth_user
return None
@LOGIN_MANAGER.user_loader
def user_loader(_id):
return authenticated_user_factory(_id)
def check_feeds_user(username, password):
if not config.get('FEEDS_USERS_DB').check_password(username, password):
return None
return MMAuthenticatedFeedUser(_id=username)
def check_admin_user(username, password):
if not config.get('USERS_DB').check_password(username, password):
return None
return MMAuthenticatedAdminUser(_id=username)
@LOGIN_MANAGER.unauthorized_handler
def unauthorized():
return 'Unauthorized', 401
def init_app(app):
global PREVENT_WRITE
global PREVENT_WRITE_GUARD
app.config['REMEMBER_COOKIE_NAME'] = None # to block remember cookie
LOGIN_MANAGER.init_app(app)
# initialize PREVENT_WRITE
PREVENT_WRITE_GUARD = gevent.lock.BoundedSemaphore()
PREVENT_WRITE = None
================================================
FILE: minemeld/flask/aaaapi.py
================================================
# Copyright 2016 Palo Alto Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import collections
from flask import request, jsonify
from flask.ext.login import current_user
from . import config
from .aaa import MMBlueprint
from .logger import LOG
__all__ = ['BLUEPRINT']
BLUEPRINT = MMBlueprint('aaa', __name__, url_prefix='/aaa')
# if you change things here change also backup/import API
API_USERS_ATTRS_ATTR = 'API_USERS_ATTRS'
FEEDS_USERS_ATTRS_ATTR = 'FEEDS_USERS_ATTRS'
FEEDS_ATTRS_ATTR = 'FEEDS_ATTRS'
Subsystem = collections.namedtuple(
'Subsystem',
['authdb', 'attrs', 'enabled', 'enabled_default'],
verbose=True
)
_SUBSYSTEM_MAP = {
'api': Subsystem(
authdb='USERS_DB',
enabled='API_AUTH_ENABLED',
enabled_default=True,
attrs=config.APIConfigDict(attribute=API_USERS_ATTRS_ATTR, level=50)
),
'feeds': Subsystem(
authdb='FEEDS_USERS_DB',
enabled='FEEDS_AUTH_ENABLED',
enabled_default=False,
attrs=config.APIConfigDict(attribute=FEEDS_USERS_ATTRS_ATTR, level=50)
)
}
_FEEDS_ATTRS = config.APIConfigDict(attribute=FEEDS_ATTRS_ATTR, level=50)
@BLUEPRINT.route('/users/current', methods=['GET'], read_write=False)
def get_current_user():
return jsonify(result={
'id': current_user.get_id(),
'read_write': current_user.is_read_write()
})
@BLUEPRINT.route('/users/<subsystem>', methods=['GET'], read_write=False)
def get_users(subsystem):
subsystem = _SUBSYSTEM_MAP.get(subsystem, None)
if subsystem is None:
return jsonify(error='Invalid subsystem'), 400
result = {
'enabled': config.get(subsystem.enabled, subsystem.enabled_default),
'users': {}
}
users = config.get(subsystem.authdb).users()
users_attrs = subsystem.attrs.value()
for u in users:
attrs = {}
if u in users_attrs:
attrs = users_attrs[u]
result['users'][u] = attrs
return jsonify(result=result)
@BLUEPRINT.route('/users/<subsystem>/<username>', methods=['PUT'], read_write=True)
def set_user_password(subsystem, username):
subsystem = _SUBSYSTEM_MAP.get(subsystem, None)
if subsystem is None:
return jsonify(error='Invalid subsystem'), 400
with config.lock():
users_db = config.get(subsystem.authdb)
if not users_db.path:
return jsonify(error='Users database not available'), 500
try:
password = request.get_json()['password']
except Exception:
return jsonify(error='Invalid request'), 400
users_db.set_password(username, password)
users_db.save()
return jsonify(result='ok')
@BLUEPRINT.route('/users/<subsystem>/<username>/attributes', methods=['POST'], read_write=True)
def set_user_attributes(subsystem, username):
subsystem = _SUBSYSTEM_MAP.get(subsystem, None)
if subsystem is None:
return jsonify(error='Invalid subsystem'), 400
with config.lock():
users_db = config.get(subsystem.authdb)
if not users_db.path:
return jsonify(error='Users database not available'), 500
if username not in users_db.users():
return jsonify(error='Unknown user'), 400
try:
attributes = request.get_json()
except Exception:
return jsonify(error='Invalid request'), 400
if not isinstance(attributes, dict):
return jsonify(error='Attributes should be a dict'), 400
subsystem.attrs.set(username, attributes)
return jsonify(result='ok')
@BLUEPRINT.route('/users/<subsystem>/<username>', methods=['DELETE'], read_write=True)
def delete_user(subsystem, username):
subsystem = _SUBSYSTEM_MAP.get(subsystem, None)
if subsystem is None:
return jsonify(error='Invalid subsystem'), 400
with config.lock():
users_db = config.get(subsystem.authdb)
if not users_db.path:
return jsonify(error='Users database not available'), 500
# delete user from database and tags
if users_db.delete(username):
users_db.save()
subsystem.attrs.delete(username)
return jsonify(result='ok')
@BLUEPRINT.route('/feeds', methods=['GET'], read_write=False)
def get_feeds():
result = {
'enabled': config.get(
_SUBSYSTEM_MAP['feeds'].enabled,
_SUBSYSTEM_MAP['feeds'].enabled_default
),
'feeds': _FEEDS_ATTRS.value()
}
return jsonify(result=result)
@BLUEPRINT.route('/feeds/<feedname>/attributes', methods=['PUT', 'POST'], read_write=True)
def set_feed_attributes(feedname):
with config.lock():
try:
attributes = request.get_json()
except Exception:
return jsonify(error='Invalid request'), 400
if not isinstance(attributes, dict):
return jsonify(error='Attributes should be a dict'), 400
_FEEDS_ATTRS.set(feedname, attributes)
return jsonify(result='ok')
@BLUEPRINT.route('/feeds/<feedname>', methods=['DELETE'], read_write=True)
def delete_feed(feedname):
with config.lock():
_FEEDS_ATTRS.delete(feedname)
return jsonify(result='ok')
@BLUEPRINT.route('/tags', methods=['GET'], read_write=False)
def get_tags():
tags = set()
for _, subsystem in _SUBSYSTEM_MAP.iteritems():
for _, attributes in subsystem.attrs.value().iteritems():
if 'tags' in attributes:
for t in attributes['tags']:
tags.add(t)
for _, attributes in _FEEDS_ATTRS.value().iteritems():
if 'tags' in attributes:
for t in attributes['tags']:
tags.add(t)
return jsonify(result=list(tags - set(['any', 'anonymous'])))
================================================
FILE: minemeld/flask/cbfeed.py
================================================
import json
import time
class CbFeed(object):
def __init__(self, feedinfo, reports):
self.data = {'feedinfo': feedinfo,
'reports': reports}
def dump(self):
return json.dumps(self.data, indent=2)
class CbFeedInfo(object):
def __init__(self, **kwargs):
self.yieldable_atts = ("category", "icon", "icon_small", "version", "provider_url",
"display_name", "summary", "tech_data", "name")
self.data = kwargs
self.data["category"] = self.data.get("category", "MineMeld")
self.data["icon"] = self.data.get("icon", MinemeldIcon.MM_icon_png)
self.data["icon_small"] = self.data.get("icon_small", MinemeldIcon.MM_icon_small_png)
self.data["version"] = self.data.get("version", "0.1")
self.data["provider_url"] = self.data.get("provider_url",
"https://live.paloaltonetworks.com/t5/MineMeld/ct-p/MineMeld")
self.data["display_name"] = self.data.get("display_name", "MineMeld Feed")
self.data["summary"] = self.data.get("summary", "Indicators routed through MineMeld")
self.data["tech_data"] = self.data.get("tech_data", "Indicators routed through MineMeld")
if "name" not in kwargs:
raise ValueError("Mandatory 'name' attribute not provided")
def dump(self):
return self.data
def iterate(self):
last_element = len(self.yieldable_atts) - 1
for idx, id in enumerate(self.yieldable_atts):
final_comma = "," if idx < last_element else ""
if isinstance(self.data[id], int):
yield "\"{}\": {}{}".format(id, self.data[id], final_comma)
else:
yield "\"{}\": \"{}\"{}".format(id, self.data[id], final_comma)
class CbReport(object):
def __init__(self, **kwargs):
# these fields are optional
self.optional = ("tags", "description")
self.yieldable_atts = ("timestamp", "id", "link", "score", "description", "title")
if "timestamp" not in kwargs:
kwargs["timestamp"] = int(time.mktime(time.gmtime()))
if "id" not in kwargs:
raise ValueError("Mandatory 'id' attribute not provided")
self.data = kwargs
self.data["link"] = self.data.get("link", "https://live.paloaltonetworks.com/t5/MineMeld/ct-p/MineMeld")
self.data["score"] = self.data.get("score", 100)
if not isinstance(self.data["score"], int):
self.data["score"] = 100
self.data["description"] = self.data.get("description", "MineMeld Generated Report")
self.data["iocs"] = self.data.get("iocs", None)
self.data["title"] = self.data.get("title", "MineMeld Generated Report")
def dump(self):
return self.data
def iterate(self):
last_element = len(self.yieldable_atts) - 1
for idx, id in enumerate(self.yieldable_atts):
final_comma = "," if idx < last_element else ""
if isinstance(self.data[id], int):
yield "\"{}\": {}{}".format(id, self.data[id], final_comma)
else:
yield "\"{}\": \"{}\"{}".format(id, self.data[id], final_comma)
class MinemeldIcon(object):
MM_icon_small_png = ("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"
"l1qW2dp/OvtV1aJ24rn//9P0dB/wPNB60PrjrEONQ2WFwWHz4z1+Tf711JPRI81HXoweP"
"mRzbepx+vLQeqZ9bP9iQ3tDdmNjYeWLyieYmj6bjv9n8Vn3S4GTlKY1Tq09TThefHjlTe"
"GbobO7ZgXNp53qbZzXfP59w/kbL1Jb2C6EXLl0MvHi+1af1zCXPSycvu18+ccX1SsNV56"
"v1bU5tx393+v14u3N7/TWXa40dbh1NnZM6T3d5d5277n/94o2QG1dvht/svBV7687t6be"
"773DvPL+bdffVvYJ7w/cXPyA8KH2o8rDikc6jqj8s/jjU7dx9qse/p+1x9OP7vZzeF09E"
"Tz73FT+lPa14pv+s9rn985P9gf0df077s+9F7ovhgZK/VP/a+tL85bG/WX+3DSYM9r0Sv"
"hp5vfKN1pvqt45vm4cihx69y343/L70g9aHmo+uH1s/xX96Njz7M+nzpi8WX5q+hn59MJ"
"I9MpLLFrKlRwEMNjQ1FYDX1QDQEuHZoQMAipLs7iUVRHZflCLwn7DsfiYVZwCqWQDELgY"
"gDJ5RtsNmAjEV9pKjdwwLoA4OY00uolQHe1ksKrzBED6MjLzRBYDUBMAX4cjI8LaRkS97"
"INm7AJzNk935JEKE5/udEyWoo++PQfCD/AMf7G3o0obnYAAAAAlwSFlzAAAWJQAAFiUBS"
"VIk8AAAAgVpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD"
"0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjp"
"SREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50"
"YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgI"
"CAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgIC"
"AgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIj4"
"KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjEwMjI8L2V4aWY6UGl4ZWxZRGlt"
"ZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+OTE2PC9leGlmOlBpe"
"GVsWERpbWVuc2lvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcm"
"llbnRhdGlvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC9"
"4OnhtcG1ldGE+Cj6cgV0AAA+rSURBVGgFzVprcFXHfd/dc859IfGSBAaHGlkgg4TAiZKm"
"7bSxnDpN/MhrYhHbsfOa1E0m0/RbP3Xq637px2YmM52J+6GeTp2HNAmNXRtjZxKRh5PJo"
"EkISIDAwjgEMEQCrMe9uuec3f5+/z1HlpBkE7dOvXDv2bOP//u1e6XV26g5p/Sg6jeXh9"
"eZzqkx19c3lGqt3NuIxDcmxbmqWW5Vtbr8+HJr/9/HBgb6g5yIp0fue++zo/d/4cCxT96"
"Tj71lzNAEMuA6R/ZmnzkTT4/037B/9BPPPz92rxs6s9f9+Own3f6RTzx74MJDqwj7jZhZ"
"Vp0rEUVgA64/oN2ib8GQWskkVoKxcJwC2bt3MD3kHo6MtvvWtkR3xHGa1qbjeOpKI17bW"
"vhgOln7a+7ZdM9T81pbCCPvXzcjlByJ36sH04GRauH5F/vXkCGtq7a6gn3nSFZ6PjbcG3"
"Lud6OTd5Ur5k8u/26uobTWkE+Eh6rXElUx7k+55nzvcMrnSu26GCETlNyzI/3rnxnt/2q"
"TOjIS19Kx/aP3/veB4/3tVTDzZjTT2dssEcmq9F3awEqdMlCx9BxkZK1TrUW3g7CrWlmY"
"wYr0rjiRc05p50xYlQytXR/8XVRQ20ygNqxrje62afotrqVmaCr5vut46j41lElZ714YZ"
"AkHHGobW7UqtFtV7eRmgffIyIrw35CRLuU3W23/cX1bqefyxFwtbtjUpi6ZuFS3kOQf/3"
"DsgVuJiDngOhiQJRAQrceNjPQXYEw7k8SCdEyRA+oFojFQSXPFrJ54Nb2Fm4aGLr05RsQ"
"Z4ROAoZ2zfz47HVNUEd7p8AFwurVNgWovq24iansdRJxf2HIBjWt7E6zophjSBzwRBKkF"
"D6ZgVApGVGLj3Qv3Ltd/AwnCMtGeO37fJnRuSmJarvLWDOZSq2xTUaly2Hgn1/X1tYGW6"
"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"
"2AAAAAASUVORK5C")
MM_icon_png = ("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"
"l1qW2dp/OvtV1aJ24rn//9P0dB/wPNB60PrjrEONQ2WFwWHz4z1+Tf711JPRI81HXoweP"
"mRzbepx+vLQeqZ9bP9iQ3tDdmNjYeWLyieYmj6bjv9n8Vn3S4GTlKY1Tq09TThefHjlTe"
"GbobO7ZgXNp53qbZzXfP59w/kbL1Jb2C6EXLl0MvHi+1af1zCXPSycvu18+ccX1SsNV56"
"v1bU5tx393+v14u3N7/TWXa40dbh1NnZM6T3d5d5277n/94o2QG1dvht/svBV7687t6be"
"773DvPL+bdffVvYJ7w/cXPyA8KH2o8rDikc6jqj8s/jjU7dx9qse/p+1x9OP7vZzeF09E"
"Tz73FT+lPa14pv+s9rn985P9gf0df077s+9F7ovhgZK/VP/a+tL85bG/WX+3DSYM9r0Sv"
"hp5vfKN1pvqt45vm4cihx69y343/L70g9aHmo+uH1s/xX96Njz7M+nzpi8WX5q+hn59MJ"
"I9MpLLFrKlRwEMNjQ1FYDX1QDQEuHZoQMAipLs7iUVRHZflCLwn7DsfiYVZwCqWQDELgY"
"gDJ5RtsNmAjEV9pKjdwwLoA4OY00uolQHe1ksKrzBED6MjLzRBYDUBMAX4cjI8LaRkS97"
"INm7AJzNk935JEKE5/udEyWoo++PQfCD/AMf7G3o0obnYAAAAAlwSFlzAAAWJQAAFiUBS"
"VIk8AAAAgRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD"
"0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjp"
"SREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50"
"YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgI"
"CAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgIC"
"AgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIj4"
"KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjk5NjwvZXhpZjpQaXhlbFlEaW1l"
"bnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj45MDI8L2V4aWY6UGl4Z"
"WxYRGltZW5zaW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaW"
"VudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g"
"6eG1wbWV0YT4KTlGaRAAAQABJREFUeAHsvQmYXNlVJvi2WHPRmirtS2qXajNZA8ZuqJDB"
"XxsGA20mhdtuFg9QYMyOh6U/BoWmjcHdA3xA21DFzLDaMMpv+gNc2GCXrZRtDIbKqrJdU"
"qm0lfaUlJJyz4h46/z/vfFSKeUWEflexI1U3CplbO/dd+6555577lk1rdVaGGhhoIWBFg"
"ZaGGhhoIWBFgZaGGhhoIWBFgZaGGhhoIWBFgZaGGhhoIWBFgZaGGhhoIWBFgZaGGhhoIW"
"BFgZaGGhhoIWBFgZaGGhhoIWBFgZaGGhhoIWBFgYeCgzoD8UoW4NsYUARDARBgDV3VO/r"
"O6l3dR2cXn9DQyeD3t6DgablA13X8NpqLQy0MNDCQJ0xEASafizoNY8fz1n5QDMqeTyv5"
"z/eW8n1D9M1LYQ8TLPdGmvdMJAP8saGgU+aP/7UgDPzoZCwrK9c+4P1CTfTYSTc1UEwld"
"b1dKFgF+52ZFcMP/bIj92ccb1+/HjePHQo78747qF+22JYD/X0twYfNQbIqJ7u7zcOHeq"
"fZjJfPpff5enFb/W94rd6vn3QDSZ3ekExbeiJFI5/hh8E+N8pWXp2zDCSr+pG6gupoOPv"
"3rrnw68QvnxeM44cyWu6nvejhrfZ+msxrGabsRa8SmKAx7d+LWce0iWjOnvnLzuv3vnKu"
"xxv/D1+UHxrpk3P6oanua6tObamBWA9vu8LZRWYlmbopmaYgZZMmZppWtrkuOaZWuazyc"
"Ta//b0rv/z8xz08SBnhf0riYQ6ANViWHVAcusRyxsD1Dcd1vs8jvLkrWPtg8P9P+75Yz+"
"ZyjrdWuBpxaKn+R7eaLqvQ06CRt0Q2imhgJ+JG/wEaQvsTNMNzcq2W5pdMPEp/acr/L0f"
"/Kb9//kOdWEzpbeZdz8M71sM62GY5dYYY8PAsy/2JEI91Qun3/+fvGD0aLbD7y4Vbc0u+"
"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"
"oDINUwJomFO6VOtRWB+YRcbk5nkbsbxYmM
gitextract_8s2k2lhp/ ├── .circleci/ │ └── config.yml ├── .gitignore ├── AUTHORS ├── LICENSE ├── NOTICE ├── README.md ├── docs/ │ ├── Makefile │ ├── architecture.rst │ ├── conf.py │ ├── configapi.rst │ ├── index.rst │ ├── internals.rst │ ├── license.rst │ ├── messages.rst │ ├── metricsapi.rst │ ├── nodeconfig.rst │ ├── schema-indicator-0-1.json │ ├── schema.rst │ ├── scripts.rst │ └── statusapi.rst ├── minemeld/ │ ├── __init__.py │ ├── chassis.py │ ├── collectd.py │ ├── comm/ │ │ ├── __init__.py │ │ └── zmqredis.py │ ├── extensions/ │ │ ├── __init__.py │ │ └── manager.py │ ├── fabric.py │ ├── flask/ │ │ ├── __init__.py │ │ ├── aaa.py │ │ ├── aaaapi.py │ │ ├── cbfeed.py │ │ ├── config.py │ │ ├── configapi.py │ │ ├── configdataapi.py │ │ ├── events.py │ │ ├── extensionsapi.py │ │ ├── feedredis.py │ │ ├── jobs.py │ │ ├── jobsapi.py │ │ ├── logger.py │ │ ├── loginapi.py │ │ ├── logsapi.py │ │ ├── main.py │ │ ├── metricsapi.py │ │ ├── mmrpc.py │ │ ├── prototypeapi.py │ │ ├── redisclient.py │ │ ├── session.py │ │ ├── sns.py │ │ ├── statusapi.py │ │ ├── supervisorapi.py │ │ ├── supervisorclient.py │ │ ├── taxiicollmgmt.py │ │ ├── taxiidiscovery.py │ │ ├── taxiipoll.py │ │ ├── taxiiutils.py │ │ ├── tracedapi.py │ │ ├── utils.py │ │ └── validateapi.py │ ├── ft/ │ │ ├── __init__.py │ │ ├── actorbase.py │ │ ├── anomali.py │ │ ├── auscert.py │ │ ├── autofocus.py │ │ ├── azure.py │ │ ├── bambenek.py │ │ ├── base.py │ │ ├── basepoller.py │ │ ├── cif.py │ │ ├── ciscoise.py │ │ ├── cofense.py │ │ ├── condition/ │ │ │ ├── BoolExpr.g4 │ │ │ ├── BoolExpr.tokens │ │ │ ├── BoolExprLexer.py │ │ │ ├── BoolExprLexer.tokens │ │ │ ├── BoolExprListener.py │ │ │ ├── BoolExprParser.py │ │ │ ├── __init__.py │ │ │ └── interface.py │ │ ├── csv.py │ │ ├── dag.py │ │ ├── dag_ng.py │ │ ├── google.py │ │ ├── http.py │ │ ├── ipop.py │ │ ├── json.py │ │ ├── local.py │ │ ├── localdb.py │ │ ├── logstash.py │ │ ├── mm.py │ │ ├── o365.py │ │ ├── op.py │ │ ├── panos.py │ │ ├── phishme.py │ │ ├── proofpoint.py │ │ ├── recordedfuture.py │ │ ├── redis.py │ │ ├── st.py │ │ ├── syslog.py │ │ ├── table.py │ │ ├── taxii.py │ │ ├── taxii2.py │ │ ├── test.py │ │ ├── threatconnect.py │ │ ├── threatq.py │ │ ├── tmt.py │ │ ├── utils.py │ │ ├── visa.py │ │ ├── vt.py │ │ └── xmpp.py │ ├── loader.py │ ├── mgmtbus.py │ ├── packages/ │ │ ├── __init__.py │ │ ├── gdns/ │ │ │ ├── LICENSE │ │ │ ├── __init__.py │ │ │ ├── _ares.pyx │ │ │ ├── cares.pxd │ │ │ ├── cares_ntop.h │ │ │ ├── cares_pton.h │ │ │ ├── dig.py │ │ │ └── dnshelper.c │ │ ├── gevent_openssl/ │ │ │ ├── COPYING │ │ │ ├── SSL.py │ │ │ └── __init__.py │ │ ├── ise/ │ │ │ ├── __init__.py │ │ │ └── ers.py │ │ └── panforest/ │ │ ├── __init__.py │ │ └── forest.py │ ├── run/ │ │ ├── __init__.py │ │ ├── cacert_merge.py │ │ ├── config.py │ │ ├── console.py │ │ ├── extgit.py │ │ ├── freeze.py │ │ ├── launcher.py │ │ └── restore.py │ ├── startupplanner.py │ ├── supervisord/ │ │ ├── __init__.py │ │ └── listener.py │ └── traced/ │ ├── __init__.py │ ├── main.py │ ├── purge.py │ ├── queryprocessor.py │ ├── storage.py │ └── writer.py ├── nodes.json ├── requirements-dev.txt ├── requirements-web.txt ├── requirements.txt ├── scripts/ │ └── prebuild-script.sh ├── setup.py ├── tests/ │ ├── comm_mock.py │ ├── empty.yml │ ├── feeds.htpasswd │ ├── integration/ │ │ └── basic/ │ │ ├── DomainHC%3Fv%3Dcarbonblack.result │ │ ├── IPv4.lst │ │ ├── IPv4HC%3Fs%3D5%26n%3D10.result │ │ ├── IPv4HC%3Fv%3Dcsv%26f%3Dconfidence%26f%3Dsources%7Cfeeds%26f%3Dindicator%7Cclientip%26tr%3D1.result │ │ ├── IPv4HC%3Fv%3Djson%26tr%3D1.result │ │ ├── IPv4HC%3Fv%3Djson-seq.result │ │ ├── IPv4HC%3Fv%3Dmwg.result │ │ ├── IPv4HC.result │ │ ├── README.md │ │ ├── URL.lst │ │ ├── URLHC%3Fs%3D5%26n%3D10.result │ │ ├── URLHC%3Fv%3Dbluecoat%26cd%3Dtest.result │ │ ├── URLHC%3Fv%3Dbluecoat.result │ │ ├── URLHC%3Fv%3Dcsv%26f%3Dconfidence%26f%3Dsources%7Cfeeds%26f%3Dindicator%7Curl.result │ │ ├── URLHC%3Fv%3Djson%26tr%3D1.result │ │ ├── URLHC%3Fv%3Djson-seq.result │ │ ├── URLHC%3Fv%3Dmwg.result │ │ ├── URLHC%3Fv%3Dpanosurl%26di%3D1.result │ │ ├── URLHC%3Fv%3Dpanosurl%26sp%3D1%26nsl%3D1.result │ │ ├── URLHC%3Fv%3Dpanosurl%26sp%3D1.result │ │ ├── URLHC%3Fv%3Dpanosurl.result │ │ ├── URLHC.result │ │ ├── domain.lst │ │ ├── gen-results.sh │ │ └── test.py │ ├── panos_mock.py │ ├── st_profile.py │ ├── test-prototype-1.yml │ ├── test_comm_amqp.py │ ├── test_device_list.yml │ ├── test_device_list2.yml │ ├── test_flask_aaa.py │ ├── test_ft_autofocus.py │ ├── test_ft_base.py │ ├── test_ft_basepoller.py │ ├── test_ft_boolexpr.py │ ├── test_ft_dag.py │ ├── test_ft_dag_devicepusher_op__show__object__registered_ip__ip_192_168_1_1__ip___registered_ip___object___show__0.xml │ ├── test_ft_dag_devicepusher_op__show__object__registered_ip__ip_192_168_1_2__ip___registered_ip___object___show__0.xml │ ├── test_ft_dag_devicepusher_op__show__object__registered_ip__tag__entry_name__mmeld_test_____tag___registered_ip___object___show__0.xml │ ├── test_ft_ipop.py │ ├── test_ft_local.py │ ├── test_ft_logstash.py │ ├── test_ft_op.py │ ├── test_ft_redis.py │ ├── test_ft_st.py │ ├── test_ft_syslog.py │ ├── test_ft_table.py │ ├── test_ft_taxii.py │ ├── test_ft_taxii_stix_package_IPv4_1_3.xml │ ├── test_ft_taxii_stix_package_IPv4_3_1.xml │ ├── test_ft_taxii_stix_package_IPv4_3_2.xml │ ├── test_ft_taxii_stix_package_IPv6_3_1.xml │ ├── test_ft_taxii_stix_package_IPv6_3_2.xml │ ├── test_localdb.yml │ ├── test_localdb2.yml │ ├── test_run_config.py │ ├── test_startupplanner.py │ ├── test_traced_queryprocessor.py │ ├── test_traced_storage.py │ ├── test_traced_writer.py │ ├── testproto.yml │ ├── traced_mock.py │ ├── traced_storage_profile.py │ └── wsgi.htpasswd └── tox.ini
SYMBOL INDEX (1840 symbols across 132 files)
FILE: minemeld/chassis.py
class Chassis (line 38) | class Chassis(object):
method __init__ (line 47) | def __init__(self, fabricclass, fabricconfig, mgmtbusconfig):
method _dynamic_load (line 76) | def _dynamic_load(self, classname):
method get_ft (line 82) | def get_ft(self, ftname):
method configure (line 85) | def configure(self, config):
method request_mgmtbus_channel (line 120) | def request_mgmtbus_channel(self, ft):
method request_rpc_channel (line 123) | def request_rpc_channel(self, ftname, ft, allowed_methods=None):
method request_pub_channel (line 128) | def request_pub_channel(self, ftname):
method request_sub_channel (line 131) | def request_sub_channel(self, ftname, ft, subname, allowed_methods=None):
method send_rpc (line 136) | def send_rpc(self, sftname, dftname, method, params, block, timeout):
method _log_actor (line 140) | def _log_actor(self):
method log (line 152) | def log(self, timestamp, nodename, log_type, value):
method _status_actor (line 160) | def _status_actor(self):
method publish_status (line 171) | def publish_status(self, timestamp, nodename, status):
method fabric_failed (line 178) | def fabric_failed(self):
method mgmtbus_failed (line 181) | def mgmtbus_failed(self):
method mgmtbus_start (line 185) | def mgmtbus_start(self):
method fts_init (line 190) | def fts_init(self):
method stop (line 196) | def stop(self):
method start (line 223) | def start(self):
FILE: minemeld/collectd.py
class CollectdClient (line 27) | class CollectdClient(object):
method __init__ (line 33) | def __init__(self, path):
method _open_socket (line 37) | def _open_socket(self):
method _readline (line 46) | def _readline(self):
method _send_cmd (line 56) | def _send_cmd(self, command):
method flush (line 73) | def flush(self, identifier=None, timeout=None):
method putval (line 84) | def putval(self, identifier, value, timestamp='N',
FILE: minemeld/comm/__init__.py
function factory (line 6) | def factory(commclass, config):
function cleanup (line 13) | def cleanup(commclass, config):
FILE: minemeld/comm/zmqredis.py
class RedisPubChannel (line 40) | class RedisPubChannel(object):
method __init__ (line 41) | def __init__(self, topic, connection_pool):
method connect (line 50) | def connect(self):
method disconnect (line 58) | def disconnect(self):
method lagger (line 64) | def lagger(self):
method gc (line 79) | def gc(self, lagger):
method publish (line 99) | def publish(self, method, params=None):
class ZMQRpcFanoutClientChannel (line 137) | class ZMQRpcFanoutClientChannel(object):
method __init__ (line 138) | def __init__(self, fanout):
method run (line 146) | def run(self):
method send_rpc (line 187) | def send_rpc(self, method, params=None, num_results=0, and_discard=Fal...
method connect (line 232) | def connect(self, context):
method disconnect (line 244) | def disconnect(self):
class ZMQRpcServerChannel (line 255) | class ZMQRpcServerChannel(object):
method __init__ (line 256) | def __init__(self, name, obj, allowed_methods=None,
method _send_result (line 271) | def _send_result(self, reply_to, id_, result=None, error=None):
method run (line 293) | def run(self):
method connect (line 345) | def connect(self, context):
method disconnect (line 371) | def disconnect(self):
class ZMQPubChannel (line 377) | class ZMQPubChannel(object):
method __init__ (line 378) | def __init__(self, topic):
method publish (line 384) | def publish(self, method, params=None):
method connect (line 409) | def connect(self, context):
method disconnect (line 418) | def disconnect(self):
class ZMQSubChannel (line 426) | class ZMQSubChannel(object):
method __init__ (line 427) | def __init__(self, name, obj, allowed_methods=None,
method run (line 442) | def run(self):
method connect (line 482) | def connect(self, context):
method disconnect (line 492) | def disconnect(self):
class RedisSubChannel (line 498) | class RedisSubChannel(object):
method __init__ (line 499) | def __init__(self, topic, connection_pool, object_,
method _callback (line 513) | def _callback(self, msg):
method connect (line 547) | def connect(self):
method disconnect (line 561) | def disconnect(self):
class ZMQRedis (line 565) | class ZMQRedis(object):
method __init__ (line 566) | def __init__(self, config):
method add_failure_listener (line 588) | def add_failure_listener(self, listener):
method request_rpc_server_channel (line 591) | def request_rpc_server_channel(self, name, obj=None, allowed_methods=N...
method request_rpc_fanout_client_channel (line 607) | def request_rpc_fanout_client_channel(self, topic):
method request_pub_channel (line 612) | def request_pub_channel(self, topic, multi_write=False):
method request_sub_channel (line 627) | def request_sub_channel(self, topic, obj=None, allowed_methods=None,
method send_rpc (line 652) | def send_rpc(self, dest, method, params,
method _ioloop (line 702) | def _ioloop(self, executor):
method _sub_ioloop (line 705) | def _sub_ioloop(self, schannel):
method _ioloop_failure (line 743) | def _ioloop_failure(self, g):
method start (line 757) | def start(self, start_dispatching=True):
method start_dispatching (line 781) | def start_dispatching(self):
method stop (line 802) | def stop(self):
method cleanup (line 850) | def cleanup(config):
FILE: minemeld/extensions/manager.py
function _egg_link_path (line 65) | def _egg_link_path(dist):
function _read_metadata (line 73) | def _read_metadata(metadata_str):
function _read_entry_points (line 77) | def _read_entry_points(ep_contents):
function _activated_extensions (line 87) | def _activated_extensions():
function _load_metadata_from_wheel (line 150) | def _load_metadata_from_wheel(extpath, extname=None):
function _load_metadata_from_dir (line 203) | def _load_metadata_from_dir(extpath):
function _is_activated (line 219) | def _is_activated(installed_extension, activated):
function get_metadata_from_wheel (line 237) | def get_metadata_from_wheel(wheelpath, wheelname=None):
function installed_extensions (line 241) | def installed_extensions(installation_dir):
function activated_extensions (line 276) | def activated_extensions():
function extensions (line 280) | def extensions(installation_dir):
function freeze (line 309) | def freeze(installation_dir):
function load_frozen_paths (line 329) | def load_frozen_paths(freeze_file):
FILE: minemeld/fabric.py
class Fabric (line 32) | class Fabric(object):
method __init__ (line 40) | def __init__(self, chassis, config, comm_class):
method request_rpc_channel (line 48) | def request_rpc_channel(self, ftname, node, allowed_methods):
method request_pub_channel (line 58) | def request_pub_channel(self, ftname):
method request_sub_channel (line 66) | def request_sub_channel(self, ftname, node, subname, allowed_methods):
method send_rpc (line 78) | def send_rpc(self, sftname, dftname, method, params,
method _comm_failure (line 99) | def _comm_failure(self):
method start (line 102) | def start(self):
method start_dispatching (line 107) | def start_dispatching(self):
method stop (line 110) | def stop(self):
function factory (line 115) | def factory(classname, chassis, config):
FILE: minemeld/flask/__init__.py
function create_app (line 27) | def create_app():
FILE: minemeld/flask/aaa.py
function disable_prevent_write (line 33) | def disable_prevent_write(locker):
function enable_prevent_write (line 42) | def enable_prevent_write(locker, timeout=900):
class MMBlueprint (line 58) | class MMBlueprint(Blueprint):
method __init__ (line 59) | def __init__(self, *args, **kwargs):
method _audit (line 69) | def _audit(self, f, audit_required):
method _login_required (line 104) | def _login_required(self, f, login_required, read_write, feeds):
method _write_prevented (line 129) | def _write_prevented(self, f, read_write):
method route (line 139) | def route(self, rule, **options):
class MMAnonynmousUser (line 156) | class MMAnonynmousUser(object):
method __init__ (line 157) | def __init__(self):
method get_id (line 160) | def get_id(self):
method is_authenticated (line 163) | def is_authenticated(self):
method is_active (line 166) | def is_active(self):
method is_anonymous (line 169) | def is_anonymous(self):
method is_read_write (line 172) | def is_read_write(self):
method check_feed (line 175) | def check_feed(self, feedname):
class MMAuthenticatedUser (line 189) | class MMAuthenticatedUser(object):
method __init__ (line 190) | def __init__(self, _id=None):
method get_id (line 193) | def get_id(self):
method is_authenticated (line 196) | def is_authenticated(self):
method is_active (line 199) | def is_active(self):
method is_anonymous (line 202) | def is_anonymous(self):
class MMAuthenticatedAdminUser (line 206) | class MMAuthenticatedAdminUser(MMAuthenticatedUser):
method __init__ (line 207) | def __init__(self, _id):
method is_read_write (line 210) | def is_read_write(self):
method check_feed (line 226) | def check_feed(self, feedname):
class MMAuthenticatedFeedUser (line 230) | class MMAuthenticatedFeedUser(MMAuthenticatedUser):
method __init__ (line 231) | def __init__(self, _id):
method is_read_write (line 234) | def is_read_write(self):
method check_feed (line 238) | def check_feed(self, feedname):
function authenticated_user_factory (line 260) | def authenticated_user_factory(_id):
function request_loader (line 279) | def request_loader(request):
function user_loader (line 308) | def user_loader(_id):
function check_feeds_user (line 312) | def check_feeds_user(username, password):
function check_admin_user (line 319) | def check_admin_user(username, password):
function unauthorized (line 327) | def unauthorized():
function init_app (line 331) | def init_app(app):
FILE: minemeld/flask/aaaapi.py
function get_current_user (line 63) | def get_current_user():
function get_users (line 71) | def get_users(subsystem):
function set_user_password (line 92) | def set_user_password(subsystem, username):
function set_user_attributes (line 114) | def set_user_attributes(subsystem, username):
function delete_user (line 141) | def delete_user(subsystem, username):
function get_feeds (line 161) | def get_feeds():
function set_feed_attributes (line 173) | def set_feed_attributes(feedname):
function delete_feed (line 189) | def delete_feed(feedname):
function get_tags (line 197) | def get_tags():
FILE: minemeld/flask/cbfeed.py
class CbFeed (line 5) | class CbFeed(object):
method __init__ (line 6) | def __init__(self, feedinfo, reports):
method dump (line 10) | def dump(self):
class CbFeedInfo (line 14) | class CbFeedInfo(object):
method __init__ (line 15) | def __init__(self, **kwargs):
method dump (line 31) | def dump(self):
method iterate (line 34) | def iterate(self):
class CbReport (line 44) | class CbReport(object):
method __init__ (line 45) | def __init__(self, **kwargs):
method dump (line 66) | def dump(self):
method iterate (line 69) | def iterate(self):
class MinemeldIcon (line 79) | class MinemeldIcon(object):
FILE: minemeld/flask/config.py
function get (line 40) | def get(key, default=None):
function store (line 63) | def store(file, value):
function lock (line 69) | def lock():
class APIConfigDict (line 73) | class APIConfigDict(object):
method __init__ (line 74) | def __init__(self, attribute, level=50):
method set (line 78) | def set(self, key, value):
method delete (line 83) | def delete(self, key):
method value (line 88) | def value(self):
function _load_config (line 92) | def _load_config(config_path):
function _load_auth_dbs (line 133) | def _load_auth_dbs(config_path):
function _config_monitor (line 164) | def _config_monitor(config_path):
function init (line 192) | def init():
FILE: minemeld/flask/configapi.py
class VersionMismatchError (line 47) | class VersionMismatchError(Exception):
class MMConfigVersion (line 51) | class MMConfigVersion(object):
method __init__ (line 52) | def __init__(self, version=None):
method __str__ (line 63) | def __str__(self):
method __repr__ (line 66) | def __repr__(self):
method __eq__ (line 69) | def __eq__(self, other):
method __ne__ (line 72) | def __ne__(self, other):
method __iadd__ (line 75) | def __iadd__(self, y):
function _lock (line 80) | def _lock(resource):
function _lock_timeout (line 92) | def _lock_timeout(resource, timeout=30):
function _unlock (line 106) | def _unlock(resource, value):
function _redlock (line 119) | def _redlock(f):
function _set_stanza (line 141) | def _set_stanza(stanza, value, version, config_key=REDIS_KEY_CONFIG):
function _get_stanza (line 157) | def _get_stanza(stanza, config_key=REDIS_KEY_CONFIG):
function _load_running_config (line 174) | def _load_running_config():
function _load_committed_config (line 178) | def _load_committed_config():
function _load_config_from_file (line 182) | def _load_config_from_file(rcpath):
function _commit_config (line 235) | def _commit_config(version):
function _config_full (line 298) | def _config_full():
function _config_info (line 311) | def _config_info():
function _create_node (line 331) | def _create_node(nodebody):
function _delete_node (line 356) | def _delete_node(nodenum, version):
function _set_node (line 373) | def _set_node(nodenum, nodebody):
function get_running_config (line 390) | def get_running_config():
function get_committed_config (line 395) | def get_committed_config():
function reload_running_config (line 401) | def reload_running_config():
function commit (line 420) | def commit():
function get_config_info (line 445) | def get_config_info():
function get_config_full (line 455) | def get_config_full():
function get_fabric (line 466) | def get_fabric():
function get_mgmtbus (line 479) | def get_mgmtbus():
function create_node (line 492) | def create_node():
function get_node (line 509) | def get_node(nodenum):
function set_node (line 528) | def set_node(nodenum):
function delete_node (line 551) | def delete_node(nodenum):
function _init_config (line 572) | def _init_config():
function init_app (line 586) | def init_app(app):
FILE: minemeld/flask/configdataapi.py
function _safe_remove (line 43) | def _safe_remove(path, g=None):
class _CDataYaml (line 50) | class _CDataYaml(object):
method __init__ (line 51) | def __init__(self, cpath, datafilename):
method read (line 55) | def read(self):
method create (line 79) | def create(self):
method append (line 104) | def append(self):
class _CDataLocalDB (line 143) | class _CDataLocalDB(object):
method __init__ (line 144) | def __init__(self, cpath, datafilename):
method read (line 149) | def read(self):
method create (line 177) | def create(self):
method _parse_text_data (line 180) | def _parse_text_data(self, data):
method append (line 252) | def append(self):
class _CDataUploadOnly (line 313) | class _CDataUploadOnly(object):
method __init__ (line 314) | def __init__(self, extension, cpath, datafilename):
method read (line 319) | def read(self):
method create (line 330) | def create(self):
class _CDataCertificate (line 356) | class _CDataCertificate(_CDataUploadOnly):
method __init__ (line 357) | def __init__(self, cpath, datafilename):
class _CDataPrivateKey (line 365) | class _CDataPrivateKey(_CDataUploadOnly):
method __init__ (line 366) | def __init__(self, cpath, datafilename):
function get_config_data (line 376) | def get_config_data(datafilename):
function save_config_data (line 394) | def save_config_data(datafilename):
function append_config_data (line 421) | def append_config_data(datafilename):
FILE: minemeld/flask/events.py
class StatusEventsSubscriber (line 16) | class StatusEventsSubscriber(object):
method __init__ (line 20) | def __init__(self, connection_pool):
method _retry_wrap (line 25) | def _retry_wrap(self):
method _listen (line 36) | def _listen(self):
method start (line 54) | def start(self):
class EventsReceiver (line 60) | class EventsReceiver(object):
method __init__ (line 61) | def __init__(self):
method _signal_receiver (line 67) | def _signal_receiver(self, sender, data):
method _generator (line 74) | def _generator(self):
method __iter__ (line 88) | def __iter__(self):
method next (line 91) | def next(self):
method close (line 96) | def close(self):
function get_EventsGenerator (line 100) | def get_EventsGenerator():
function teardown (line 112) | def teardown(exception):
function init_app (line 119) | def init_app(app, redis_url):
FILE: minemeld/flask/extensionsapi.py
function _get_extensions (line 49) | def _get_extensions():
function _build_activate_args (line 57) | def _build_activate_args(ext_path):
function _build_deactivate_args (line 82) | def _build_deactivate_args(extension_name):
function _find_running_job (line 96) | def _find_running_job(extension, jobs):
function _load_frozen_paths (line 107) | def _load_frozen_paths():
function _update_freeze_file (line 125) | def _update_freeze_file():
function _extensions_changed (line 141) | def _extensions_changed(activated_path, deactivated_path, g):
function _safe_remove (line 159) | def _safe_remove(path, g=None):
function list_extensions (line 167) | def list_extensions():
function activate_extension (line 185) | def activate_extension(extension):
function deactivate_extension (line 241) | def deactivate_extension(extension):
function uninstall_extension (line 297) | def uninstall_extension(extension):
function upload_extension (line 349) | def upload_extension():
function get_git_refs (line 407) | def get_git_refs():
function install_from_git (line 452) | def install_from_git():
function init_app (line 505) | def init_app(app):
FILE: minemeld/flask/feedredis.py
function _translate_ip_ranges (line 47) | def _translate_ip_ranges(indicator, value=None):
function _extract_cidrs (line 60) | def _extract_cidrs(indicator):
function _buffer (line 71) | def _buffer():
function generate_panosurl_feed (line 80) | def generate_panosurl_feed(feed, start, num, desc, value, **kwargs):
function generate_plain_feed (line 139) | def generate_plain_feed(feed, start, num, desc, value, **kwargs):
function generate_json_feed (line 182) | def generate_json_feed(feed, start, num, desc, value, **kwargs):
function generate_csv_feed (line 245) | def generate_csv_feed(feed, start, num, desc, value, **kwargs):
function generate_mwg_feed (line 353) | def generate_mwg_feed(feed, start, num, desc, value, **kwargs):
function generate_bluecoat_feed (line 410) | def generate_bluecoat_feed(feed, start, num, desc, value, **kwargs):
function generate_carbon_black (line 451) | def generate_carbon_black(feed, start, num, desc, value, **kwargs):
function get_feed_content (line 556) | def get_feed_content(feed):
FILE: minemeld/flask/jobs.py
class JobsManager (line 51) | class JobsManager(object):
method __init__ (line 52) | def __init__(self, connection_pool):
method _safe_rmtree (line 56) | def _safe_rmtree(self, path):
method _safe_remove (line 59) | def _safe_remove(self, path):
method _get_job_status (line 65) | def _get_job_status(self, jobpid, jobhash):
method _collect_job (line 85) | def _collect_job(self, jobdata):
method _job_monitor_glet (line 95) | def _job_monitor_glet(self, job_group, jobid, description, args, data):
method _job_timeout_glet (line 166) | def _job_timeout_glet(self, job_group, jobid, timeout):
method delete_job (line 189) | def delete_job(self, job_group, jobid):
method get_jobs (line 206) | def get_jobs(self, job_group):
method exec_job (line 235) | def exec_job(self, job_group, description, args, data=None, callback=N...
function get_JobsManager (line 254) | def get_JobsManager():
function teardown (line 262) | def teardown(exception):
function init_app (line 277) | def init_app(app):
FILE: minemeld/flask/jobsapi.py
function get_jobs (line 32) | def get_jobs(job_group):
function get_job (line 39) | def get_job(job_group, jobid):
function get_job_log (line 48) | def get_job_log(job_group, jobid):
FILE: minemeld/flask/logger.py
class MMLogger (line 11) | class MMLogger(object):
method __init__ (line 12) | def __init__(self):
method init_app (line 18) | def init_app(self, app):
method _init_logger (line 23) | def _init_logger(self, logger):
method debug (line 34) | def debug(self, *args, **kwargs):
method info (line 40) | def info(self, *args, **kwargs):
method warning (line 46) | def warning(self, *args, **kwargs):
method error (line 52) | def error(self, *args, **kwargs):
method critical (line 58) | def critical(self, *args, **kwargs):
method exception (line 64) | def exception(self, *args, **kwargs):
method audit (line 70) | def audit(self, user_id, action_name, params, msg=None):
FILE: minemeld/flask/loginapi.py
function login (line 29) | def login():
function logout (line 47) | def logout():
FILE: minemeld/flask/logsapi.py
function get_minemeld_engine_log (line 29) | def get_minemeld_engine_log():
function get_minemeld_web_log (line 38) | def get_minemeld_web_log():
FILE: minemeld/flask/metricsapi.py
function _list_metrics (line 41) | def _list_metrics(prefix=None):
function _fetch_metric (line 50) | def _fetch_metric(cc, metric, type_=None,
function get_metrics (line 95) | def get_metrics():
function get_node_type_metrics (line 100) | def get_node_type_metrics(nodetype):
function get_global_metrics (line 140) | def get_global_metrics():
function get_node_metrics (line 183) | def get_node_metrics(node):
function get_metric (line 224) | def get_metric(node, metric):
FILE: minemeld/flask/mmrpc.py
class _MMMasterConnection (line 20) | class _MMMasterConnection(object):
method __init__ (line 21) | def __init__(self):
method _open_channel (line 28) | def _open_channel(self):
method _send_cmd (line 38) | def _send_cmd(self, method, params={}):
method status (line 48) | def status(self):
method stop (line 51) | def stop(self):
class _MMRpcClient (line 57) | class _MMRpcClient(object):
method __init__ (line 58) | def __init__(self):
method _open_channel (line 65) | def _open_channel(self):
method send_raw_cmd (line 75) | def send_raw_cmd(self, target, method, params={}, timeout=10):
method send_cmd (line 80) | def send_cmd(self, target, method, params={}, timeout=10):
method stop (line 85) | def stop(self):
function get_mmmaster (line 91) | def get_mmmaster():
function get_mmrpcclient (line 102) | def get_mmrpcclient():
function teardown (line 113) | def teardown(exception):
function init_app (line 125) | def init_app(app):
FILE: minemeld/flask/prototypeapi.py
function _prototype_paths (line 43) | def _prototype_paths():
function _local_library_path (line 78) | def _local_library_path(prototypename):
function list_prototypes (line 116) | def list_prototypes():
function get_prototype (line 148) | def get_prototype(prototypename):
function add_local_prototype (line 213) | def add_local_prototype(prototypename):
function delete_local_prototype (line 285) | def delete_local_prototype(prototypename):
function reset_prototype_paths (line 326) | def reset_prototype_paths():
FILE: minemeld/flask/redisclient.py
function get_SR (line 21) | def get_SR():
function teardown (line 29) | def teardown(exception):
function init_app (line 44) | def init_app(app):
FILE: minemeld/flask/session.py
class RedisSession (line 31) | class RedisSession(werkzeug.datastructures.CallbackDict, flask.sessions....
method __init__ (line 32) | def __init__(self, initial=None, sid=None, new=False):
class RedisSessionInterface (line 41) | class RedisSessionInterface(flask.sessions.SessionInterface):
method __init__ (line 45) | def __init__(self, redis_=None, prefix='mm-session:'):
method generate_sid (line 57) | def generate_sid(self):
method get_redis_expiration_time (line 60) | def get_redis_expiration_time(self, app, session):
method open_session (line 63) | def open_session(self, app, request):
method save_session (line 82) | def save_session(self, app, session, response):
function init_app (line 112) | def init_app(app, redis_url):
FILE: minemeld/flask/sns.py
class Sns (line 19) | class Sns(object):
method __init__ (line 20) | def __init__(self, path):
method get_status (line 26) | def get_status(self):
method _init_uuid (line 29) | def _init_uuid(self):
method _send_message (line 69) | def _send_message(self, kvmessage):
method _hello_world (line 86) | def _hello_world(self):
method make_wish (line 89) | def make_wish(self, message):
method send_stats (line 93) | def send_stats(self, stats):
function init_app (line 98) | def init_app():
FILE: minemeld/flask/statusapi.py
class _PubSubWrapper (line 45) | class _PubSubWrapper(object):
method __init__ (line 46) | def __init__(self, subscription, pattern=False):
method _listen (line 58) | def _listen(self):
method _msg_generator (line 63) | def _msg_generator(self):
method __iter__ (line 80) | def __iter__(self):
method next (line 83) | def next(self):
method close (line 86) | def close(self):
function get_query_events (line 97) | def get_query_events(quuid):
function get_status_events (line 112) | def get_status_events():
function get_system_status (line 120) | def get_system_status():
function get_system_info (line 136) | def get_system_info():
function get_minemeld_status (line 145) | def get_minemeld_status():
function get_minemeld_running_config (line 161) | def get_minemeld_running_config():
function hup_node (line 174) | def hup_node(nodename):
function signal_node (line 191) | def signal_node(nodename, signalname):
function _clean_local_backup (line 219) | def _clean_local_backup(local_backup_file, g):
function generate_local_backup (line 237) | def generate_local_backup():
function get_local_backup (line 288) | def get_local_backup(jobid):
function import_local_backup (line 298) | def import_local_backup():
function _cleanup_after_restore (line 360) | def _cleanup_after_restore(backup_file, locker, g):
function restore_local_backup (line 366) | def restore_local_backup(backup_id):
function sns_wish (line 467) | def sns_wish():
FILE: minemeld/flask/supervisorapi.py
function _restart_engine (line 38) | def _restart_engine():
function service_status (line 79) | def service_status():
function start_minemeld_engine (line 109) | def start_minemeld_engine():
function stop_minemeld_engine (line 116) | def stop_minemeld_engine():
function restart_minemeld_engine (line 123) | def restart_minemeld_engine():
function hup_minemeld_web (line 137) | def hup_minemeld_web():
FILE: minemeld/flask/supervisorclient.py
function get_Supervisor (line 14) | def get_Supervisor():
function teardown (line 35) | def teardown(exception):
function init_app (line 41) | def init_app(app):
FILE: minemeld/flask/taxiicollmgmt.py
function taxii_collection_mgmt_service (line 40) | def taxii_collection_mgmt_service():
FILE: minemeld/flask/taxiidiscovery.py
function taxii_discovery_service (line 55) | def taxii_discovery_service():
FILE: minemeld/flask/taxiipoll.py
function _oldest_indicator_timestamp (line 46) | def _oldest_indicator_timestamp(feed):
function _indicators_feed (line 59) | def _indicators_feed(feed, excbegtime, incendtime):
function data_feed_11 (line 97) | def data_feed_11(rmsgid, cname, excbegtime, incendtime):
function taxii_poll_service (line 146) | def taxii_poll_service():
FILE: minemeld/flask/taxiiutils.py
function taxii_make_response (line 24) | def taxii_make_response(m11):
function taxii_make_response_10 (line 34) | def taxii_make_response_10(m10):
function taxii_check (line 44) | def taxii_check(f):
function get_taxii_feeds (line 69) | def get_taxii_feeds():
FILE: minemeld/flask/tracedapi.py
function traced_query (line 35) | def traced_query():
function traced_kill_query (line 79) | def traced_kill_query(query_uuid):
function traced_purge_all (line 93) | def traced_purge_all():
FILE: minemeld/flask/utils.py
class DirSnapshot (line 23) | class DirSnapshot(object):
method __init__ (line 24) | def __init__(self, path, regex=None):
method _init_snapshot (line 27) | def _init_snapshot(self, path, regex):
method __eq__ (line 42) | def __eq__(self, other):
method __ne__ (line 45) | def __ne__(self, other):
function running_config_path (line 49) | def running_config_path():
function committed_config_path (line 58) | def committed_config_path():
function running_config (line 67) | def running_config():
function committed_config (line 74) | def committed_config():
function safe_remove (line 81) | def safe_remove(path):
FILE: minemeld/flask/validateapi.py
function _return_validation_error (line 30) | def _return_validation_error(msg):
function validate_syslogminerrule (line 37) | def validate_syslogminerrule():
FILE: minemeld/ft/__init__.py
function factory (line 4) | def factory(classname, name, chassis, config):
class ft_states (line 14) | class ft_states(object):
FILE: minemeld/ft/actorbase.py
class ActorBaseFT (line 15) | class ActorBaseFT(BaseFT):
method __init__ (line 16) | def __init__(self, *args, **kwargs):
method command_rebuild (line 23) | def command_rebuild(self):
method checkpoint (line 27) | def checkpoint(self, **kwargs):
method update (line 31) | def update(self, **kwargs):
method withdraw (line 35) | def withdraw(self, **kwargs):
method _actor_loop (line 38) | def _actor_loop(self):
method start (line 60) | def start(self):
method stop (line 68) | def stop(self):
FILE: minemeld/ft/anomali.py
class Intelligence (line 38) | class Intelligence(basepoller.BasePollerFT):
method __init__ (line 39) | def __init__(self, name, chassis, config):
method configure (line 44) | def configure(self):
method _load_side_config (line 74) | def _load_side_config(self):
method _calc_age_out (line 91) | def _calc_age_out(self, indicator, attributes):
method _process_item (line 107) | def _process_item(self, item):
method _build_iterator (line 166) | def _build_iterator(self, now):
method hup (line 240) | def hup(self, source=None):
method gc (line 246) | def gc(name, config=None):
FILE: minemeld/ft/auscert.py
class MaliciousURLFeed (line 26) | class MaliciousURLFeed(http.HttpFT):
method configure (line 27) | def configure(self):
method _load_side_config (line 40) | def _load_side_config(self):
method _build_iterator (line 53) | def _build_iterator(self, now):
method hup (line 99) | def hup(self, source=None):
FILE: minemeld/ft/autofocus.py
class ExportList (line 33) | class ExportList(basepoller.BasePollerFT):
method configure (line 34) | def configure(self):
method _load_side_config (line 52) | def _load_side_config(self):
method _process_item (line 67) | def _process_item(self, row):
method _check_for_ip (line 76) | def _check_for_ip(self, indicator):
method _type_of_indicator (line 123) | def _type_of_indicator(self, indicator):
method _build_iterator (line 133) | def _build_iterator(self, now):
method hup (line 155) | def hup(self, source=None):
method gc (line 161) | def gc(name, config=None):
FILE: minemeld/ft/azure.py
function _build_IPv4 (line 44) | def _build_IPv4(nodename, region, iprange):
function _build_IP (line 66) | def _build_IP(nodename, address_prefix, **keywords):
class AzureXML (line 92) | class AzureXML(basepoller.BasePollerFT):
method configure (line 93) | def configure(self):
method _process_item (line 99) | def _process_item(self, item):
method _build_request (line 103) | def _build_request(self, now):
method _build_iterator (line 111) | def _build_iterator(self, now):
class AzureJSON (line 176) | class AzureJSON(basepoller.BasePollerFT):
method configure (line 177) | def configure(self):
method _process_item (line 185) | def _process_item(self, item):
method _build_iterator (line 189) | def _build_iterator(self, now):
FILE: minemeld/ft/bambenek.py
class Miner (line 15) | class Miner(csv.CSVFT):
FILE: minemeld/ft/base.py
class _Filters (line 37) | class _Filters(object):
method __init__ (line 44) | def __init__(self, filters):
method apply (line 65) | def apply(self, origin=None, method=None, indicator=None, value=None):
function _counting (line 116) | def _counting(statsname):
class BaseFT (line 132) | class BaseFT(object):
method __init__ (line 192) | def __init__(self, name, chassis, config):
method state (line 220) | def state(self):
method state (line 224) | def state(self, value):
method read_checkpoint (line 231) | def read_checkpoint(self):
method create_checkpoint (line 301) | def create_checkpoint(self, value):
method remove_checkpoint (line 324) | def remove_checkpoint(self):
method _saved_state_restore (line 331) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 334) | def _saved_state_create(self):
method configure (line 337) | def configure(self):
method connect (line 348) | def connect(self, inputs, output):
method apply_infilters (line 383) | def apply_infilters(self, origin, method, indicator, value):
method apply_outfilters (line 391) | def apply_outfilters(self, origin, method, indicator, value):
method do_rpc (line 399) | def do_rpc(self, dftname, method, block=True, timeout=30, **kwargs):
method emit_update (line 404) | def emit_update(self, indicator, value):
method emit_withdraw (line 432) | def emit_withdraw(self, indicator, value=None):
method emit_checkpoint (line 460) | def emit_checkpoint(self, value):
method update (line 470) | def update(self, source=None, indicator=None, value=None):
method filtered_update (line 516) | def filtered_update(self, source=None, indicator=None, value=None):
method withdraw (line 520) | def withdraw(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 560) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method checkpoint (line 564) | def checkpoint(self, source=None, value=None):
method _full_trace_timeout (line 591) | def _full_trace_timeout(self, timeout):
method enable_full_trace (line 598) | def enable_full_trace(self, timeout=600):
method publish_status (line 613) | def publish_status(self, force=False):
method _internal_publish_status (line 619) | def _internal_publish_status(self):
method mgmtbus_state_info (line 628) | def mgmtbus_state_info(self):
method mgmtbus_initialize (line 635) | def mgmtbus_initialize(self):
method mgmtbus_rebuild (line 641) | def mgmtbus_rebuild(self):
method mgmtbus_reset (line 648) | def mgmtbus_reset(self):
method mgmtbus_status (line 655) | def mgmtbus_status(self):
method mgmtbus_checkpoint (line 675) | def mgmtbus_checkpoint(self, value=None):
method mgmtbus_hup (line 686) | def mgmtbus_hup(self, source=None):
method mgmtbus_signal (line 689) | def mgmtbus_signal(self, source=None, signal=None, **kwargs):
method initialize (line 696) | def initialize(self):
method rebuild (line 699) | def rebuild(self):
method reset (line 702) | def reset(self):
method get_state (line 705) | def get_state(self):
method get (line 708) | def get(self, source=None, indicator=None):
method get_all (line 711) | def get_all(self, source=None):
method get_range (line 714) | def get_range(self, source=None, index=None, from_key=None, to_key=None):
method length (line 718) | def length(self, source=None):
method hup (line 721) | def hup(self, source=None):
method trace (line 724) | def trace(self, action, indicator, **kwargs):
method start (line 745) | def start(self):
method stop (line 754) | def stop(self):
method gc (line 770) | def gc(name, config=None):
FILE: minemeld/ft/basepoller.py
class _BaseBPTable (line 43) | class _BaseBPTable(object):
method __init__ (line 44) | def __init__(self, table):
method get (line 47) | def get(self, indicator, itype=None):
method delete (line 50) | def delete(self, indicator, itype=None):
method put (line 53) | def put(self, indicator, value):
method query (line 56) | def query(self, *args, **kwargs):
method length (line 59) | def length(self):
method close (line 62) | def close(self):
method __del__ (line 65) | def __del__(self):
class _BPTable_v0 (line 69) | class _BPTable_v0(_BaseBPTable):
method __init__ (line 70) | def __init__(self, table):
class _BPTable_v1 (line 78) | class _BPTable_v1(_BaseBPTable):
method __init__ (line 79) | def __init__(self, table, type_in_key):
method get (line 96) | def get(self, indicator, itype=None):
method delete (line 102) | def delete(self, indicator, itype=None):
method put (line 108) | def put(self, indicator, value):
method query (line 115) | def query(self, *args, **kwargs):
method _type_key_query (line 124) | def _type_key_query(self, *args, **kwargs):
method _type_key_query_with_value (line 128) | def _type_key_query_with_value(self, *args, **kwargs):
method _type_key (line 132) | def _type_key(self, indicator, itype):
method _type_key_indicator (line 138) | def _type_key_indicator(self, key):
function _bptable_factory (line 142) | def _bptable_factory(name, truncate=False, type_in_key=False):
class IndicatorStatus (line 167) | class IndicatorStatus(object):
method __init__ (line 183) | def __init__(self, indicator, attributes, itable, now, in_feed_thresho...
class BasePollerFT (line 201) | class BasePollerFT(base.BaseFT):
method __init__ (line 300) | def __init__(self, name, chassis, config):
method configure (line 323) | def configure(self):
method _saved_state_restore (line 351) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 358) | def _saved_state_create(self):
method _saved_state_reset (line 364) | def _saved_state_reset(self):
method _initialize_table (line 368) | def _initialize_table(self, truncate=False):
method initialize (line 375) | def initialize(self):
method rebuild (line 378) | def rebuild(self):
method reset (line 384) | def reset(self):
method state (line 389) | def state(self, value):
method _controlled_emit_update (line 397) | def _controlled_emit_update(self, indicator, value):
method _controlled_emit_withdraw (line 404) | def _controlled_emit_withdraw(self, indicator, value):
method _age_out (line 411) | def _age_out(self):
method _flush (line 444) | def _flush(self):
method _sudden_death (line 472) | def _sudden_death(self):
method _collect_garbage (line 491) | def _collect_garbage(self):
method _compare_attributes (line 508) | def _compare_attributes(self, oa, na):
method _update_attributes (line 522) | def _update_attributes(self, current, _new, current_run, new_run):
method _aggregate_iterator (line 532) | def _aggregate_iterator(self, iterator):
method _aggregate_process_item (line 568) | def _aggregate_process_item(self, item):
method _polling_loop (line 571) | def _polling_loop(self):
method _rebuild (line 718) | def _rebuild(self):
method _poll (line 728) | def _poll(self):
method _actor_loop (line 769) | def _actor_loop(self):
method _poll_loop (line 815) | def _poll_loop(self):
method _age_out_loop (line 863) | def _age_out_loop(self):
method _calc_age_out (line 881) | def _calc_age_out(self, indicator, attributes):
method _huppable_wait (line 895) | def _huppable_wait(self, deltat):
method mgmtbus_status (line 909) | def mgmtbus_status(self):
method mgmtbus_signal (line 920) | def mgmtbus_signal(self, source=None, signal=None, **kwargs):
method sub_state (line 936) | def sub_state(self):
method sub_state (line 940) | def sub_state(self, value):
method hup (line 950) | def hup(self, source=None):
method length (line 954) | def length(self, source=None):
method start (line 957) | def start(self):
method stop (line 975) | def stop(self):
method gc (line 990) | def gc(name, config=None):
FILE: minemeld/ft/cif.py
class Feed (line 32) | class Feed(basepoller.BasePollerFT):
method configure (line 33) | def configure(self):
method _load_side_config (line 55) | def _load_side_config(self):
method _process_item (line 77) | def _process_item(self, item):
method _build_iterator (line 118) | def _build_iterator(self, now):
method hup (line 162) | def hup(self, source=None):
method gc (line 168) | def gc(name, config=None):
FILE: minemeld/ft/ciscoise.py
class ErsSgt (line 24) | class ErsSgt(basepoller.BasePollerFT):
method configure (line 25) | def configure(self):
method _load_side_config (line 52) | def _load_side_config(self):
method _process_item (line 74) | def _process_item(self, item):
method _build_iterator (line 77) | def _build_iterator(self, now):
method hup (line 96) | def hup(self, source=None):
method gc (line 102) | def gc(name, config=None):
FILE: minemeld/ft/cofense.py
class Triage (line 42) | class Triage(basepoller.BasePollerFT):
method configure (line 43) | def configure(self):
method _load_side_config (line 78) | def _load_side_config(self):
method _process_item (line 107) | def _process_item(self, item):
method _build_iterator (line 144) | def _build_iterator(self, now):
method _check_number_of_pages (line 161) | def _check_number_of_pages(self, dt_poll_start):
method _iterate_over_pages (line 169) | def _iterate_over_pages(self, start_date, num_of_pages):
method _perform_api_call (line 177) | def _perform_api_call(self, start_date, page=None):
method hup (line 199) | def hup(self, source=None):
method gc (line 205) | def gc(name, config=None):
FILE: minemeld/ft/condition/BoolExprLexer.py
function serializedATN (line 12) | def serializedATN():
class BoolExprLexer (line 59) | class BoolExprLexer(Lexer):
method __init__ (line 100) | def __init__(self, input=None, output=sys.stdout):
FILE: minemeld/ft/condition/BoolExprListener.py
class BoolExprListener (line 8) | class BoolExprListener(ParseTreeListener):
method enterBooleanExpression (line 11) | def enterBooleanExpression(self, ctx):
method exitBooleanExpression (line 15) | def exitBooleanExpression(self, ctx):
method enterExpression (line 20) | def enterExpression(self, ctx):
method exitExpression (line 24) | def exitExpression(self, ctx):
method enterFunctionExpression (line 29) | def enterFunctionExpression(self, ctx):
method exitFunctionExpression (line 33) | def exitFunctionExpression(self, ctx):
method enterNoArgs (line 38) | def enterNoArgs(self, ctx):
method exitNoArgs (line 42) | def exitNoArgs(self, ctx):
method enterOneOrMoreArgs (line 47) | def enterOneOrMoreArgs(self, ctx):
method exitOneOrMoreArgs (line 51) | def exitOneOrMoreArgs(self, ctx):
method enterComparator (line 56) | def enterComparator(self, ctx):
method exitComparator (line 60) | def exitComparator(self, ctx):
method enterValue (line 65) | def enterValue(self, ctx):
method exitValue (line 69) | def exitValue(self, ctx):
FILE: minemeld/ft/condition/BoolExprParser.py
function serializedATN (line 11) | def serializedATN():
class BoolExprParser (line 33) | class BoolExprParser ( Parser ):
method __init__ (line 82) | def __init__(self, input, output=sys.stdout):
class BooleanExpressionContext (line 90) | class BooleanExpressionContext(ParserRuleContext):
method __init__ (line 92) | def __init__(self, parser, parent=None, invokingState=-1):
method expression (line 96) | def expression(self):
method comparator (line 100) | def comparator(self):
method value (line 104) | def value(self):
method getRuleIndex (line 108) | def getRuleIndex(self):
method enterRule (line 111) | def enterRule(self, listener):
method exitRule (line 115) | def exitRule(self, listener):
method booleanExpression (line 122) | def booleanExpression(self):
class ExpressionContext (line 142) | class ExpressionContext(ParserRuleContext):
method __init__ (line 144) | def __init__(self, parser, parent=None, invokingState=-1):
method JAVASCRIPTIDENTIFIER (line 148) | def JAVASCRIPTIDENTIFIER(self):
method functionExpression (line 151) | def functionExpression(self):
method getRuleIndex (line 155) | def getRuleIndex(self):
method enterRule (line 158) | def enterRule(self, listener):
method exitRule (line 162) | def exitRule(self, listener):
method expression (line 169) | def expression(self):
class FunctionExpressionContext (line 198) | class FunctionExpressionContext(ParserRuleContext):
method __init__ (line 200) | def __init__(self, parser, parent=None, invokingState=-1):
method JAVASCRIPTIDENTIFIER (line 204) | def JAVASCRIPTIDENTIFIER(self):
method noArgs (line 207) | def noArgs(self):
method oneOrMoreArgs (line 211) | def oneOrMoreArgs(self):
method getRuleIndex (line 215) | def getRuleIndex(self):
method enterRule (line 218) | def enterRule(self, listener):
method exitRule (line 222) | def exitRule(self, listener):
method functionExpression (line 229) | def functionExpression(self):
class NoArgsContext (line 259) | class NoArgsContext(ParserRuleContext):
method __init__ (line 261) | def __init__(self, parser, parent=None, invokingState=-1):
method getRuleIndex (line 266) | def getRuleIndex(self):
method enterRule (line 269) | def enterRule(self, listener):
method exitRule (line 273) | def exitRule(self, listener):
method noArgs (line 280) | def noArgs(self):
class OneOrMoreArgsContext (line 298) | class OneOrMoreArgsContext(ParserRuleContext):
method __init__ (line 300) | def __init__(self, parser, parent=None, invokingState=-1):
method expression (line 304) | def expression(self, i=None):
method value (line 311) | def value(self, i=None):
method getRuleIndex (line 318) | def getRuleIndex(self):
method enterRule (line 321) | def enterRule(self, listener):
method exitRule (line 325) | def exitRule(self, listener):
method oneOrMoreArgs (line 332) | def oneOrMoreArgs(self):
class ComparatorContext (line 377) | class ComparatorContext(ParserRuleContext):
method __init__ (line 379) | def __init__(self, parser, parent=None, invokingState=-1):
method getRuleIndex (line 384) | def getRuleIndex(self):
method enterRule (line 387) | def enterRule(self, listener):
method exitRule (line 391) | def exitRule(self, listener):
method comparator (line 398) | def comparator(self):
class ValueContext (line 420) | class ValueContext(ParserRuleContext):
method __init__ (line 422) | def __init__(self, parser, parent=None, invokingState=-1):
method STRING (line 426) | def STRING(self):
method NUMBER (line 429) | def NUMBER(self):
method getRuleIndex (line 432) | def getRuleIndex(self):
method enterRule (line 435) | def enterRule(self, listener):
method exitRule (line 439) | def exitRule(self, listener):
method value (line 446) | def value(self):
FILE: minemeld/ft/condition/interface.py
class _BECompiler (line 28) | class _BECompiler(BoolExprListener):
method exitExpression (line 29) | def exitExpression(self, ctx):
method exitComparator (line 32) | def exitComparator(self, ctx):
method exitValue (line 47) | def exitValue(self, ctx):
class Condition (line 60) | class Condition(object):
method __init__ (line 61) | def __init__(self, s):
method _parse_boolexpr (line 64) | def _parse_boolexpr(self, s):
method eval (line 78) | def eval(self, i):
FILE: minemeld/ft/csv.py
class CSVFT (line 37) | class CSVFT(basepoller.BasePollerFT):
method configure (line 76) | def configure(self):
method _load_side_config (line 111) | def _load_side_config(self):
method _process_item (line 130) | def _process_item(self, item):
method _build_request (line 136) | def _build_request(self, now):
method _build_iterator (line 149) | def _build_iterator(self, now):
method _gzipped_line_splitter (line 194) | def _gzipped_line_splitter(self, response):
method hup (line 221) | def hup(self, source=None):
method gc (line 227) | def gc(name, config=None):
FILE: minemeld/ft/dag.py
class DevicePusher (line 42) | class DevicePusher(gevent.Greenlet):
method __init__ (line 43) | def __init__(self, device, prefix, watermark, attributes, persistent):
method put (line 64) | def put(self, op, address, value):
method _get_registered_ip_tags (line 68) | def _get_registered_ip_tags(self, ip):
method _get_all_registered_ips (line 85) | def _get_all_registered_ips(self):
method _dag_message (line 105) | def _dag_message(self, type_, addresses):
method _user_id (line 138) | def _user_id(self, cmd=None):
method _tags_from_value (line 159) | def _tags_from_value(self, value):
method _push (line 203) | def _push(self, op, address, value):
method _init_resync (line 217) | def _init_resync(self):
method _run (line 281) | def _run(self):
class DagPusher (line 299) | class DagPusher(actorbase.ActorBaseFT):
method __init__ (line 300) | def __init__(self, name, chassis, config):
method configure (line 314) | def configure(self):
method _initialize_table (line 336) | def _initialize_table(self, truncate=False):
method initialize (line 340) | def initialize(self):
method rebuild (line 343) | def rebuild(self):
method reset (line 347) | def reset(self):
method _validate_ip (line 350) | def _validate_ip(self, indicator, value):
method filtered_update (line 391) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 427) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method _age_out_run (line 448) | def _age_out_run(self):
method _spawn_device_pusher (line 484) | def _spawn_device_pusher(self, device):
method _device_pusher_died (line 501) | def _device_pusher_died(self, g):
method _load_device_list (line 527) | def _load_device_list(self):
method _huppable_wait (line 553) | def _huppable_wait(self, wait_time):
method _device_list_monitor (line 559) | def _device_list_monitor(self):
method mgmtbus_status (line 585) | def mgmtbus_status(self):
method length (line 592) | def length(self, source=None):
method start (line 595) | def start(self):
method stop (line 609) | def stop(self):
method hup (line 625) | def hup(self, source=None):
method gc (line 630) | def gc(name, config=None):
FILE: minemeld/ft/dag_ng.py
function _api_wrapper (line 53) | def _api_wrapper(x):
class DevicePusher (line 78) | class DevicePusher(gevent.Greenlet):
method __init__ (line 79) | def __init__(self, device, prefix, watermark, attributes, persistent):
method _valid_device_version (line 101) | def _valid_device_version(self):
method _set_canary (line 126) | def _set_canary(self):
method _test_canary (line 137) | def _test_canary(self):
method put (line 175) | def put(self, op, address, value):
method _get_all_registered_ips (line 180) | def _get_all_registered_ips(self):
method _dag_message (line 242) | def _dag_message(self, type_, addresses,
method _user_id (line 288) | def _user_id(self, cmd=None):
method _tags_from_value (line 309) | def _tags_from_value(self, value):
method _push (line 357) | def _push(self, op, addresses):
method _init_resync (line 371) | def _init_resync(self):
method _run (line 438) | def _run(self):
class DagPusher (line 501) | class DagPusher(actorbase.ActorBaseFT):
method __init__ (line 502) | def __init__(self, name, chassis, config):
method configure (line 516) | def configure(self):
method _initialize_table (line 538) | def _initialize_table(self, truncate=False):
method initialize (line 542) | def initialize(self):
method rebuild (line 545) | def rebuild(self):
method reset (line 549) | def reset(self):
method _validate_ip (line 552) | def _validate_ip(self, indicator, value):
method filtered_update (line 593) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 629) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method _age_out_run (line 650) | def _age_out_run(self):
method _spawn_device_pusher (line 686) | def _spawn_device_pusher(self, device):
method _device_pusher_died (line 703) | def _device_pusher_died(self, g):
method _load_device_list (line 736) | def _load_device_list(self):
method _huppable_wait (line 762) | def _huppable_wait(self, wait_time):
method _device_list_monitor (line 768) | def _device_list_monitor(self):
method mgmtbus_status (line 794) | def mgmtbus_status(self):
method length (line 801) | def length(self, source=None):
method start (line 804) | def start(self):
method stop (line 818) | def stop(self):
method hup (line 834) | def hup(self, source=None):
method gc (line 839) | def gc(name, config=None):
FILE: minemeld/ft/google.py
class GoogleSPF (line 31) | class GoogleSPF(basepoller.BasePollerFT):
method configure (line 32) | def configure(self):
method _process_item (line 42) | def _process_item(self, item):
method _resolve_spf (line 46) | def _resolve_spf(self, dig, name):
method _build_IPv4 (line 73) | def _build_IPv4(self, netblock, ipnetwork):
method _build_IPv6 (line 91) | def _build_IPv6(self, netblock, ipnetwork):
method _build_iterator (line 109) | def _build_iterator(self, now):
class GoogleNetBlocks (line 142) | class GoogleNetBlocks(GoogleSPF):
class GoogleCloudNetBlocks (line 148) | class GoogleCloudNetBlocks(GoogleSPF):
FILE: minemeld/ft/http.py
class HttpFT (line 32) | class HttpFT(basepoller.BasePollerFT):
method configure (line 100) | def configure(self):
method _process_item (line 145) | def _process_item(self, line):
method _build_iterator (line 178) | def _build_iterator(self, now):
FILE: minemeld/ft/ipop.py
class MWUpdate (line 32) | class MWUpdate(object):
method __init__ (line 33) | def __init__(self, start, end, uuids):
method indicator (line 42) | def indicator(self):
method __repr__ (line 45) | def __repr__(self):
method __hash__ (line 48) | def __hash__(self):
method __eq__ (line 51) | def __eq__(self, other):
class AggregateIPv4FT (line 56) | class AggregateIPv4FT(actorbase.ActorBaseFT):
method __init__ (line 57) | def __init__(self, name, chassis, config):
method configure (line 62) | def configure(self):
method _initialize_tables (line 68) | def _initialize_tables(self, truncate=False):
method initialize (line 77) | def initialize(self):
method rebuild (line 80) | def rebuild(self):
method reset (line 83) | def reset(self):
method _indicator_key (line 86) | def _indicator_key(self, indicator, source):
method _calc_indicator_value (line 89) | def _calc_indicator_value(self, uuids, additional_uuid=None, additiona...
method _merge_values (line 118) | def _merge_values(self, origin, ov, nv):
method _add_indicator (line 129) | def _add_indicator(self, origin, indicator, value):
method _calc_ipranges (line 151) | def _calc_ipranges(self, start, end):
method _range_from_indicator (line 227) | def _range_from_indicator(self, indicator):
method _endpoints_from_range (line 249) | def _endpoints_from_range(self, start, end):
method filtered_update (line 283) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 351) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method _send_indicators (line 420) | def _send_indicators(self, source=None, from_key=None, to_key=None):
method get (line 435) | def get(self, source=None, indicator=None):
method get_all (line 448) | def get_all(self, source=None):
method get_range (line 452) | def get_range(self, source=None, index=None, from_key=None, to_key=None):
method length (line 468) | def length(self, source=None):
method stop (line 471) | def stop(self):
method gc (line 483) | def gc(name, config=None):
FILE: minemeld/ft/json.py
class SimpleJSON (line 31) | class SimpleJSON(basepoller.BasePollerFT):
method configure (line 75) | def configure(self):
method _load_side_config (line 123) | def _load_side_config(self):
method hup (line 139) | def hup(self, source=None):
method gc (line 145) | def gc(name, config=None):
method _process_item (line 194) | def _process_item(self, item):
method _build_iterator (line 221) | def _build_iterator(self, now):
FILE: minemeld/ft/local.py
class YamlFT (line 27) | class YamlFT(basepoller.BasePollerFT):
method __init__ (line 28) | def __init__(self, name, chassis, config):
method configure (line 33) | def configure(self):
method _flush (line 44) | def _flush(self):
method _process_item (line 48) | def _process_item(self, item):
method _load_yaml (line 57) | def _load_yaml(self):
method _build_iterator (line 70) | def _build_iterator(self, now):
method gc (line 100) | def gc(name, config=None):
class YamlIPv4FT (line 124) | class YamlIPv4FT(YamlFT):
method _process_item (line 125) | def _process_item(self, item):
class YamlURLFT (line 131) | class YamlURLFT(YamlFT):
method _process_item (line 132) | def _process_item(self, item):
class YamlDomainFT (line 138) | class YamlDomainFT(YamlFT):
method _process_item (line 139) | def _process_item(self, item):
class YamlIPv6FT (line 145) | class YamlIPv6FT(YamlFT):
method _process_item (line 146) | def _process_item(self, item):
FILE: minemeld/ft/localdb.py
function dbconnection (line 33) | def dbconnection(path):
class Miner (line 41) | class Miner(basepoller.BasePollerFT):
method __init__ (line 42) | def __init__(self, name, chassis, config):
method configure (line 47) | def configure(self):
method _collect_garbage (line 66) | def _collect_garbage(self):
method _calc_age_out (line 90) | def _calc_age_out(self, indicator, attributes):
method _process_item (line 96) | def _process_item(self, item):
method _updates_iterator (line 108) | def _updates_iterator(self, last_successful_run):
method _build_iterator (line 113) | def _build_iterator(self, now):
method hup (line 123) | def hup(self, source=None):
method gc (line 127) | def gc(name, config=None):
FILE: minemeld/ft/logstash.py
class LogstashOutput (line 28) | class LogstashOutput(actorbase.ActorBaseFT):
method __init__ (line 29) | def __init__(self, name, chassis, config):
method configure (line 34) | def configure(self):
method connect (line 40) | def connect(self, inputs, output):
method _connect_logstash (line 44) | def _connect_logstash(self):
method initialize (line 53) | def initialize(self):
method rebuild (line 56) | def rebuild(self):
method reset (line 59) | def reset(self):
method _send_logstash (line 62) | def _send_logstash(self, message, source=None, indicator=None, value=N...
method filtered_update (line 103) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 112) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method length (line 120) | def length(self, source=None):
FILE: minemeld/ft/mm.py
class JSONSEQMiner (line 32) | class JSONSEQMiner(basepoller.BasePollerFT):
method configure (line 48) | def configure(self):
method _load_side_config (line 68) | def _load_side_config(self):
method _process_item (line 84) | def _process_item(self, item):
method _json_seq_iterator (line 87) | def _json_seq_iterator(self, r):
method _build_iterator (line 95) | def _build_iterator(self, now):
method hup (line 125) | def hup(self, source=None):
FILE: minemeld/ft/o365.py
function _build_IPv4 (line 43) | def _build_IPv4(source, address):
function _build_IPv6 (line 53) | def _build_IPv6(source, address):
function _build_URL (line 63) | def _build_URL(source, url):
function _xpath_lower_case (line 73) | def _xpath_lower_case(context, a):
class O365XML (line 77) | class O365XML(basepoller.BasePollerFT):
method configure (line 78) | def configure(self):
method _process_item (line 92) | def _process_item(self, item):
method _build_request (line 96) | def _build_request(self, now):
method _o365_iterator (line 104) | def _o365_iterator(self, now):
method _build_iterator (line 174) | def _build_iterator(self, now):
method _extract_products (line 187) | def _extract_products(self, rtree):
class O365API (line 205) | class O365API(basepoller.BasePollerFT):
method __init__ (line 206) | def __init__(self, name, chassis, config):
method configure (line 212) | def configure(self):
method _load_side_config (line 232) | def _load_side_config(self):
method _saved_state_restore (line 246) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 257) | def _saved_state_create(self):
method _saved_state_reset (line 265) | def _saved_state_reset(self):
method _check_version (line 271) | def _check_version(self):
method _process_item (line 308) | def _process_item(self, item):
method _analyze_item (line 311) | def _analyze_item(self, item):
method _iterator (line 346) | def _iterator(self, array, latest_version):
method _build_iterator (line 372) | def _build_iterator(self, now):
method hup (line 413) | def hup(self, source=None):
FILE: minemeld/ft/op.py
class AggregateFT (line 27) | class AggregateFT(actorbase.ActorBaseFT):
method __init__ (line 30) | def __init__(self, name, chassis, config):
method configure (line 36) | def configure(self):
method _initialize_table (line 42) | def _initialize_table(self, truncate=False):
method initialize (line 45) | def initialize(self):
method rebuild (line 48) | def rebuild(self):
method reset (line 51) | def reset(self):
method _indicator_key (line 54) | def _indicator_key(self, indicator, source):
method _is_whitelist (line 57) | def _is_whitelist(self, s):
method _emit_update_indicator (line 63) | def _emit_update_indicator(self, indicator):
method _merge_values (line 84) | def _merge_values(self, source, ov, nv):
method _add_indicator (line 94) | def _add_indicator(self, source, indicator, value):
method filtered_update (line 111) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 141) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method get (line 183) | def get(self, source=None, indicator=None):
method get_all (line 198) | def get_all(self, source=None):
method get_range (line 201) | def get_range(self, source=None, index=None, from_key=None, to_key=None):
method length (line 233) | def length(self, source=None):
method stop (line 236) | def stop(self):
method gc (line 248) | def gc(name, config=None):
FILE: minemeld/ft/panos.py
class CheckpointSet (line 31) | class CheckpointSet(Exception):
class InterruptablePanForest (line 34) | class InterruptablePanForest(minemeld.packages.panforest.PanForest):
method __init__ (line 35) | def __init__(self, wobject, xapi=None, log_type=None, filter=None,
method sleep (line 46) | def sleep(self, t):
function _age_out_in_usecs (line 52) | def _age_out_in_usecs(val):
function _sleeper (line 66) | def _sleeper(slot, maxretries):
class PanOSLogsAPIFT (line 74) | class PanOSLogsAPIFT(base.BaseFT):
method __init__ (line 75) | def __init__(self, name, chassis, config):
method configure (line 88) | def configure(self):
method _initialize_tables (line 104) | def _initialize_tables(self, truncate=False):
method initialize (line 113) | def initialize(self):
method rebuild (line 116) | def rebuild(self):
method reset (line 120) | def reset(self):
method emit_checkpoint (line 123) | def emit_checkpoint(self, value):
method _age_out_loop (line 127) | def _age_out_loop(self, fieldidx):
method _run (line 149) | def _run(self):
method length (line 216) | def length(self, source=None):
method start (line 219) | def start(self):
method stop (line 232) | def stop(self):
FILE: minemeld/ft/phishme.py
class Intelligence (line 40) | class Intelligence(basepoller.BasePollerFT):
method __init__ (line 41) | def __init__(self, name, chassis, config):
method configure (line 46) | def configure(self):
method _load_side_config (line 88) | def _load_side_config(self):
method _saved_state_restore (line 105) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 110) | def _saved_state_create(self):
method _saved_state_reset (line 116) | def _saved_state_reset(self):
method _update_attributes (line 120) | def _update_attributes(self, current, _new, current_run, new_run):
method _convert_block (line 159) | def _convert_block(self, block):
method _process_item (line 198) | def _process_item(self, item):
method _build_iterator (line 224) | def _build_iterator(self, now):
method _threathq_backfill (line 240) | def _threathq_backfill(self, now):
method _threathq_update (line 301) | def _threathq_update(self, now):
method _group_changes_in_pages (line 362) | def _group_changes_in_pages(self, ichanges):
method _retrieve_threats (line 392) | def _retrieve_threats(self, pages):
method _filter_changes (line 436) | def _filter_changes(self, change):
method hup (line 457) | def hup(self, source=None):
method gc (line 463) | def gc(name, config=None):
FILE: minemeld/ft/proofpoint.py
class ETIntelligence (line 72) | class ETIntelligence(basepoller.BasePollerFT):
method __init__ (line 75) | def __init__(self, name, chassis, config):
method configure (line 80) | def configure(self):
method _load_side_config (line 99) | def _load_side_config(self):
method _process_row (line 120) | def _process_row(self, row):
method _process_item (line 181) | def _process_item(self, item):
method _build_iterator (line 184) | def _build_iterator(self, now):
method hup (line 255) | def hup(self, source=None):
method gc (line 261) | def gc(name, config=None):
class EmergingThreatsIP (line 280) | class EmergingThreatsIP(ETIntelligence):
method _process_item (line 283) | def _process_item(self, row):
class EmergingThreatsDomain (line 308) | class EmergingThreatsDomain(ETIntelligence):
method _process_item (line 311) | def _process_item(self, row):
FILE: minemeld/ft/recordedfuture.py
class IPRiskList (line 29) | class IPRiskList(csv.CSVFT):
method configure (line 30) | def configure(self):
method _load_side_config (line 46) | def _load_side_config(self):
method _process_item (line 59) | def _process_item(self, row):
method _build_iterator (line 115) | def _build_iterator(self, now):
method _build_request (line 123) | def _build_request(self, now):
method hup (line 135) | def hup(self, source=None):
method gc (line 141) | def gc(name, config=None):
class DomainRiskList (line 160) | class DomainRiskList(csv.CSVFT):
method configure (line 161) | def configure(self):
method _load_side_config (line 177) | def _load_side_config(self):
method _process_item (line 190) | def _process_item(self, row):
method _build_iterator (line 229) | def _build_iterator(self, now):
method _build_request (line 237) | def _build_request(self, now):
method hup (line 249) | def hup(self, source=None):
method gc (line 255) | def gc(name, config=None):
class MasterRiskList (line 274) | class MasterRiskList(csv.CSVFT):
method configure (line 275) | def configure(self):
method _load_side_config (line 294) | def _load_side_config(self):
method _process_item (line 319) | def _process_item(self, row):
method _check_hash_type (line 386) | def _check_hash_type(entity):
method _build_iterator (line 396) | def _build_iterator(self, now):
method _build_request (line 443) | def _build_request(self, now):
method hup (line 471) | def hup(self, source=None):
method gc (line 477) | def gc(name, config=None):
FILE: minemeld/ft/redis.py
class RedisSet (line 28) | class RedisSet(actorbase.ActorBaseFT):
method __init__ (line 29) | def __init__(self, name, chassis, config):
method configure (line 38) | def configure(self):
method connect (line 51) | def connect(self, inputs, output):
method read_checkpoint (line 55) | def read_checkpoint(self):
method create_checkpoint (line 107) | def create_checkpoint(self, value):
method remove_checkpoint (line 123) | def remove_checkpoint(self):
method _connect_redis (line 127) | def _connect_redis(self):
method initialize (line 135) | def initialize(self):
method rebuild (line 138) | def rebuild(self):
method reset (line 143) | def reset(self):
method _add_indicator (line 148) | def _add_indicator(self, score, indicator, value):
method _delete_indicator (line 164) | def _delete_indicator(self, indicator):
method filtered_update (line 176) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 189) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method length (line 192) | def length(self, source=None):
method gc (line 196) | def gc(name, config=None):
FILE: minemeld/ft/st.py
class ST (line 43) | class ST(object):
method __init__ (line 44) | def __init__(self, name, epsize, truncate=False,
method _split_interval (line 64) | def _split_interval(self, start, end, lower, upper):
method _segment_key (line 78) | def _segment_key(self, start, end, uuid_=None, level=None):
method _split_segment_key (line 99) | def _split_segment_key(self, key):
method _endpoint_key (line 103) | def _endpoint_key(self, endpoint, level=None, type_=None, uuid_=None):
method _split_endpoint_key (line 122) | def _split_endpoint_key(self, k):
method close (line 127) | def close(self):
method put (line 130) | def put(self, uuid_, start, end, level=0):
method delete (line 161) | def delete(self, uuid_, start, end, level=0):
method cover (line 189) | def cover(self, value):
method query_endpoints (line 221) | def query_endpoints(self, start=None, stop=None, reverse=False,
FILE: minemeld/ft/syslog.py
class SyslogMatcher (line 49) | class SyslogMatcher(actorbase.ActorBaseFT):
method __init__ (line 50) | def __init__(self, name, chassis, config):
method configure (line 57) | def configure(self):
method _initialize_tables (line 69) | def _initialize_tables(self, truncate=False):
method initialize (line 81) | def initialize(self):
method rebuild (line 84) | def rebuild(self):
method reset (line 87) | def reset(self):
method filtered_update (line 91) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 124) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method _handle_ip (line 148) | def _handle_ip(self, ip, source=True, message=None):
method _handle_url (line 192) | def _handle_url(self, url, message=None):
method _handle_syslog_message (line 217) | def _handle_syslog_message(self, message):
method _amqp_callback (line 230) | def _amqp_callback(self, msg):
method _amqp_consumer (line 244) | def _amqp_consumer(self):
method _connect_logstash (line 283) | def _connect_logstash(self):
method _send_logstash (line 295) | def _send_logstash(self, message=None, indicator=None,
method mgmtbus_status (line 340) | def mgmtbus_status(self):
method length (line 345) | def length(self, source=None):
method start (line 349) | def start(self):
method stop (line 357) | def stop(self):
method gc (line 368) | def gc(name, config=None):
class SyslogMiner (line 375) | class SyslogMiner(base.BaseFT):
method __init__ (line 376) | def __init__(self, name, chassis, config):
method configure (line 392) | def configure(self):
method _initialize_table (line 431) | def _initialize_table(self, truncate=False):
method initialize (line 436) | def initialize(self):
method rebuild (line 439) | def rebuild(self):
method reset (line 445) | def reset(self):
method _compile_rule (line 448) | def _compile_rule(self, name, f):
method _load_side_config (line 493) | def _load_side_config(self):
method state (line 521) | def state(self, value):
method _command_rebuild (line 527) | def _command_rebuild(self):
method _command_age_out (line 536) | def _command_age_out(self):
method _calc_age_out (line 562) | def _calc_age_out(self, indicator, attributes):
method _apply_rule (line 576) | def _apply_rule(self, f, message):
method _handle_syslog_message (line 614) | def _handle_syslog_message(self, message):
method _actor_loop (line 658) | def _actor_loop(self):
method _age_out_loop (line 697) | def _age_out_loop(self):
method _amqp_callback (line 710) | def _amqp_callback(self, msg):
method _amqp_consumer (line 726) | def _amqp_consumer(self):
method length (line 773) | def length(self, source=None):
method start (line 776) | def start(self):
method stop (line 789) | def stop(self):
method hup (line 806) | def hup(self, source=None):
method gc (line 811) | def gc(name, config=None):
FILE: minemeld/ft/table.py
class InvalidTableException (line 96) | class InvalidTableException(Exception):
class Table (line 100) | class Table(object):
method __init__ (line 101) | def __init__(self, name, truncate=False, bloom_filter_bits=0):
method _init_db (line 122) | def _init_db(self):
method _read_metadata (line 135) | def _read_metadata(self):
method _get (line 184) | def _get(self, key):
method __del__ (line 192) | def __del__(self):
method get_custom_metadata (line 195) | def get_custom_metadata(self):
method set_custom_metadata (line 201) | def set_custom_metadata(self, metadata=None):
method close (line 209) | def close(self):
method exists (line 219) | def exists(self, key):
method get (line 226) | def get(self, key):
method delete (line 238) | def delete(self, key):
method _indicator_key (line 255) | def _indicator_key(self, key):
method _indicator_key_version (line 258) | def _indicator_key_version(self, key):
method _index_key (line 261) | def _index_key(self, idxid, value, lastidxid=None):
method _last_global_id_key (line 279) | def _last_global_id_key(self, idxid):
method create_index (line 282) | def create_index(self, attribute):
method put (line 300) | def put(self, key, value):
method query (line 347) | def query(self, index=None, from_key=None, to_key=None,
method _query_by_indicator (line 374) | def _query_by_indicator(self, from_key=None, to_key=None,
method _query_by_index (line 405) | def _query_by_index(self, index, from_key=None, to_key=None,
method _compact_loop (line 466) | def _compact_loop(self):
method _upgrade_from_s0 (line 491) | def _upgrade_from_s0(self):
FILE: minemeld/ft/taxii.py
function set_id_namespace (line 84) | def set_id_namespace(uri, name):
class TaxiiClient (line 90) | class TaxiiClient(basepoller.BasePollerFT):
method __init__ (line 91) | def __init__(self, name, chassis, config):
method configure (line 99) | def configure(self):
method _load_side_config (line 177) | def _load_side_config(self):
method _saved_state_restore (line 204) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 209) | def _saved_state_create(self):
method _saved_state_reset (line 215) | def _saved_state_reset(self):
method _build_taxii_client (line 219) | def _build_taxii_client(self):
method _call_taxii_service (line 271) | def _call_taxii_service(self, service_url, tc, request):
method _discover_services (line 287) | def _discover_services(self, tc):
method _check_collections (line 316) | def _check_collections(self, tc):
method _poll_fulfillment_request (line 373) | def _poll_fulfillment_request(self, tc, result_id, result_part_number):
method _poll_collection (line 387) | def _poll_collection(self, tc, begin=None, end=None):
method _incremental_poll_collection (line 483) | def _incremental_poll_collection(self, taxii_client, begin, end):
method _handle_content_blocks (line 507) | def _handle_content_blocks(self, content_blocks, objects):
method _decode_observable (line 586) | def _decode_observable(self, o):
method _decode_object_properties (line 631) | def _decode_object_properties(self, op, odict=None):
method _decode_ttp (line 1014) | def _decode_ttp(self, t):
method _process_item (line 1031) | def _process_item(self, item):
method _build_iterator (line 1111) | def _build_iterator(self, now):
method _flush (line 1155) | def _flush(self):
method hup (line 1159) | def hup(self, source=None):
method gc (line 1165) | def gc(name, config=None):
function _stix_ip_observable (line 1217) | def _stix_ip_observable(namespace, indicator, value):
function _stix_email_addr_observable (line 1258) | def _stix_email_addr_observable(namespace, indicator, value):
function _stix_domain_observable (line 1280) | def _stix_domain_observable(namespace, indicator, value):
function _stix_url_observable (line 1299) | def _stix_url_observable(namespace, indicator, value):
function _stix_hash_observable (line 1319) | def _stix_hash_observable(namespace, indicator, value):
class DataFeed (line 1373) | class DataFeed(actorbase.ActorBaseFT):
method __init__ (line 1374) | def __init__(self, name, chassis, config):
method configure (line 1384) | def configure(self):
method connect (line 1425) | def connect(self, inputs, output):
method read_checkpoint (line 1429) | def read_checkpoint(self):
method create_checkpoint (line 1433) | def create_checkpoint(self, value):
method remove_checkpoint (line 1437) | def remove_checkpoint(self):
method _connect_redis (line 1441) | def _connect_redis(self):
method _read_oldest_indicator (line 1449) | def _read_oldest_indicator(self):
method initialize (line 1460) | def initialize(self):
method rebuild (line 1463) | def rebuild(self):
method reset (line 1468) | def reset(self):
method _add_indicator (line 1473) | def _add_indicator(self, score, indicator, value):
method _delete_indicator (line 1618) | def _delete_indicator(self, indicator_id):
method _age_out_run (line 1629) | def _age_out_run(self):
method filtered_update (line 1657) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 1663) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method length (line 1667) | def length(self, source=None):
method start (line 1670) | def start(self):
method stop (line 1675) | def stop(self):
method gc (line 1687) | def gc(name, config=None):
FILE: minemeld/ft/taxii2.py
class Taxii2Client (line 49) | class Taxii2Client(basepoller.BasePollerFT):
method __init__ (line 50) | def __init__(self, name, chassis, config):
method configure (line 57) | def configure(self):
method _load_side_config (line 101) | def _load_side_config(self):
method _saved_state_restore (line 154) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 159) | def _saved_state_create(self):
method _saved_state_reset (line 165) | def _saved_state_reset(self):
method _set_accept_header (line 169) | def _set_accept_header(self, session):
method _build_taxii2_client (line 195) | def _build_taxii2_client(self):
method _get_api_root (line 212) | def _get_api_root(self):
method _is_uuid (line 234) | def _is_uuid(self, val, ver):
method _get_collection (line 246) | def _get_collection(self):
method _clean_indicator (line 272) | def _clean_indicator(self, sub_pattern_value):
method _detect_and_map_type (line 281) | def _detect_and_map_type(self, i_type, sub_pattern_type):
method _convert_stix2_obj_to_mm_obj (line 289) | def _convert_stix2_obj_to_mm_obj(self, obj, rels, ttps):
method _explore (line 349) | def _explore(self, root, types):
method _poll_taxii21_server (line 361) | def _poll_taxii21_server(self):
method _poll_taxii20_server (line 409) | def _poll_taxii20_server(self):
method _poll_and_filter_collection (line 471) | def _poll_and_filter_collection(self, begin=None, end=None):
method _incremental_poll_collection (line 517) | def _incremental_poll_collection(self, begin, end):
method _process_item (line 537) | def _process_item(self, item):
method _manage_time (line 540) | def _manage_time(self, now):
method _check_args (line 560) | def _check_args(self):
method _build_iterator (line 586) | def _build_iterator(self, now):
method _flush (line 599) | def _flush(self):
method hup (line 603) | def hup(self, source=None):
method gc (line 609) | def gc(name, config=None):
FILE: minemeld/ft/test.py
class TestMiner (line 15) | class TestMiner(base.BaseFT):
method __init__ (line 16) | def __init__(self, name, chassis, config):
method configure (line 21) | def configure(self):
method initialize (line 27) | def initialize(self):
method rebuild (line 30) | def rebuild(self):
method reset (line 33) | def reset(self):
method _run (line 36) | def _run(self):
method length (line 63) | def length(self, source=None):
method start (line 66) | def start(self):
method stop (line 74) | def stop(self):
class TestFeed (line 83) | class TestFeed(base.BaseFT):
method __init__ (line 84) | def __init__(self, name, chassis, config):
method configure (line 87) | def configure(self):
method read_checkpoint (line 92) | def read_checkpoint(self):
method create_checkpoint (line 95) | def create_checkpoint(self, value):
method initialize (line 98) | def initialize(self):
method rebuild (line 101) | def rebuild(self):
method reset (line 104) | def reset(self):
method filtered_update (line 108) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 115) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method length (line 118) | def length(self, source=None):
class FaultyConfig (line 122) | class FaultyConfig(base.BaseFT):
method configure (line 123) | def configure(self):
method initialize (line 128) | def initialize(self):
method rebuild (line 131) | def rebuild(self):
method reset (line 134) | def reset(self):
method length (line 137) | def length(self, source=None):
class FaultyInit (line 141) | class FaultyInit(base.BaseFT):
method __init__ (line 142) | def __init__(self, name, chassis, config):
method configure (line 145) | def configure(self):
method initialize (line 148) | def initialize(self):
method rebuild (line 151) | def rebuild(self):
method reset (line 154) | def reset(self):
method length (line 157) | def length(self, source=None):
FILE: minemeld/ft/threatconnect.py
class ThreatConnect (line 40) | class ThreatConnect(object):
method __init__ (line 51) | def __init__(self, api_secret, api_key, api_url, api_base_uri, owner):
method prepare_get (line 58) | def prepare_get(self, uri):
method __call__ (line 64) | def __call__(self, r):
method _detect_ip_version (line 69) | def _detect_ip_version(self, ip_addr):
method _detect_sha_version (line 84) | def _detect_sha_version(self, hash):
method group_indicator_processing (line 90) | def group_indicator_processing(self, item, group_type, group_id, f_see...
method general_processing (line 111) | def general_processing(self, item, indicator_map, f_seen, l_seen):
method ip_processing (line 131) | def ip_processing(self, item, indicator_list, f_seen, l_seen):
method _paginate_request (line 147) | def _paginate_request(self, entry_point, entity, from_timestamp=None):
method indicator_iterator (line 181) | def indicator_iterator(self, last_tc_run):
method groups_iterator (line 199) | def groups_iterator(self, groups):
class TCMiner (line 207) | class TCMiner(BasePollerFT):
method configure (line 217) | def configure(self):
method _load_side_config (line 240) | def _load_side_config(self):
method _saved_state_restore (line 256) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 261) | def _saved_state_create(self):
method _saved_state_reset (line 266) | def _saved_state_reset(self):
method hup (line 270) | def hup(self, source=None):
method gc (line 276) | def gc(name, config=None):
class IndicatorsMiner (line 294) | class IndicatorsMiner(TCMiner):
method configure (line 297) | def configure(self):
method _build_iterator (line 301) | def _build_iterator(self, now):
method _process_item (line 314) | def _process_item(self, item):
class GroupsMiner (line 330) | class GroupsMiner(TCMiner):
method configure (line 333) | def configure(self):
method _build_iterator (line 342) | def _build_iterator(self, now):
method _process_item (line 351) | def _process_item(self, item):
FILE: minemeld/ft/threatq.py
class Export (line 31) | class Export(basepoller.BasePollerFT):
method configure (line 58) | def configure(self):
method _load_side_config (line 72) | def _load_side_config(self):
method _process_item (line 87) | def _process_item(self, line):
method _build_iterator (line 147) | def _build_iterator(self, now):
method hup (line 175) | def hup(self, source=None):
method gc (line 181) | def gc(name, config=None):
FILE: minemeld/ft/tmt.py
class DTIAPI (line 33) | class DTIAPI(basepoller.BasePollerFT):
method __init__ (line 37) | def __init__(self, name, chassis, config):
method configure (line 42) | def configure(self):
method _load_side_config (line 78) | def _load_side_config(self):
method _process_row (line 91) | def _process_row(self, row):
method _process_item (line 112) | def _process_item(self, item):
method _tmerge (line 122) | def _tmerge(self, indicator, value):
method _build_iterator (line 140) | def _build_iterator(self, now):
method hup (line 204) | def hup(self, source=None):
method gc (line 210) | def gc(name, config=None):
FILE: minemeld/ft/utils.py
function utc_millisec (line 30) | def utc_millisec():
function dt_to_millisec (line 34) | def dt_to_millisec(dt):
function interval_in_sec (line 41) | def interval_in_sec(val):
function age_out_in_millisec (line 59) | def age_out_in_millisec(val):
function _merge_atomic_values (line 74) | def _merge_atomic_values(op, v1, v2):
function _merge_array (line 80) | def _merge_array(v1, v2):
class RWLock (line 99) | class RWLock(object):
method __init__ (line 100) | def __init__(self):
method lock (line 110) | def lock(self):
method unlock (line 120) | def unlock(self):
method rlock (line 130) | def rlock(self):
method runlock (line 143) | def runlock(self):
method __enter__ (line 152) | def __enter__(self):
method __exit__ (line 155) | def __exit__(self, type, value, traceback):
function parse_age_out (line 162) | def parse_age_out(s, age_out_bases=None, default_base=None):
class GThrottled (line 200) | class GThrottled(object):
method __init__ (line 201) | def __init__(self, f, wait):
method later (line 212) | def later(self):
method __call__ (line 218) | def __call__(self, *args, **kwargs):
method cancel (line 241) | def cancel(self):
FILE: minemeld/ft/visa.py
class VTI (line 42) | class VTI(json.SimpleJSON):
method configure (line 49) | def configure(self):
method _process_item (line 59) | def _process_item(self, item):
method _build_iterator (line 111) | def _build_iterator(self, now):
method _detect_ip_version (line 168) | def _detect_ip_version(self, ip_addr):
method _detect_sha_version (line 183) | def _detect_sha_version(self, hash_value):
method _saved_state_restore (line 189) | def _saved_state_restore(self, saved_state):
method _saved_state_create (line 194) | def _saved_state_create(self):
method _saved_state_reset (line 199) | def _saved_state_reset(self):
FILE: minemeld/ft/vt.py
class Notifications (line 32) | class Notifications(json.SimpleJSON):
method __init__ (line 33) | def __init__(self, name, chassis, config):
method configure (line 38) | def configure(self):
method _load_side_config (line 54) | def _load_side_config(self):
method _process_item (line 68) | def _process_item(self, item):
method _build_iterator (line 81) | def _build_iterator(self, now):
method hup (line 90) | def hup(self, source=None):
method gc (line 96) | def gc(name, config=None):
FILE: minemeld/ft/xmpp.py
class XMPPOutput (line 34) | class XMPPOutput(base.BaseFT):
method __init__ (line 35) | def __init__(self, name, chassis, config):
method configure (line 49) | def configure(self):
method _load_side_config (line 65) | def _load_side_config(self):
method connect (line 85) | def connect(self, inputs, output):
method initialize (line 89) | def initialize(self):
method rebuild (line 92) | def rebuild(self):
method reset (line 95) | def reset(self):
method _read_sequence_number (line 98) | def _read_sequence_number(self):
method _write_sequence_number (line 108) | def _write_sequence_number(self):
method filtered_update (line 116) | def filtered_update(self, source=None, indicator=None, value=None):
method filtered_withdraw (line 120) | def filtered_withdraw(self, source=None, indicator=None, value=None):
method _xmpp_publish (line 123) | def _xmpp_publish(self, cmd, data=None):
method _xmpp_session_start (line 146) | def _xmpp_session_start(self, event):
method _xmpp_disconnected (line 157) | def _xmpp_disconnected(self, event):
method _start_xmpp_client (line 161) | def _start_xmpp_client(self):
method _publisher (line 201) | def _publisher(self):
method _run (line 225) | def _run(self):
method length (line 255) | def length(self, source=None):
method hup (line 258) | def hup(self, source=None):
method mgmtbus_checkpoint (line 263) | def mgmtbus_checkpoint(self, value=None):
method start (line 267) | def start(self):
method stop (line 275) | def stop(self):
class XMPPMiner (line 285) | class XMPPMiner(op.AggregateFT):
method __init__ (line 286) | def __init__(self, name, chassis, config):
method configure (line 294) | def configure(self):
method _load_side_config (line 310) | def _load_side_config(self):
method _xmpp_session_start (line 330) | def _xmpp_session_start(self, event):
method _xmpp_publish (line 341) | def _xmpp_publish(self, msg):
method _start_xmpp_client (line 419) | def _start_xmpp_client(self):
method _run (line 459) | def _run(self):
method start (line 489) | def start(self):
method stop (line 496) | def stop(self):
method hup (line 504) | def hup(self, source=None):
FILE: minemeld/loader.py
function _conflicts (line 27) | def _conflicts(requirements, installed):
function _initialize_entry_point_group (line 46) | def _initialize_entry_point_group(entrypoint_group):
function bump_workingset (line 81) | def bump_workingset():
function list (line 88) | def list(entrypoint_group):
function map (line 96) | def map(entrypoint_group):
function load (line 104) | def load(entrypoint_group, entrypoint_name):
FILE: minemeld/mgmtbus.py
class MgmtbusMaster (line 63) | class MgmtbusMaster(object):
method __init__ (line 72) | def __init__(self, ftlist, config, comm_class, comm_config, num_chassis):
method rpc_status (line 115) | def rpc_status(self):
method rpc_chassis_ready (line 120) | def rpc_chassis_ready(self, chassis_id=None):
method wait_for_chassis (line 133) | def wait_for_chassis(self, timeout=60):
method start_chassis (line 142) | def start_chassis(self):
method _send_cmd (line 149) | def _send_cmd(self, command, to_slaves=True, params=None, and_discard=...
method _send_cmd_and_wait (line 178) | def _send_cmd_and_wait(self, command, to_slaves=True, timeout=60):
method _send_node_cmd (line 193) | def _send_node_cmd(self, nodename, command, params=None):
method init_graph (line 218) | def init_graph(self, config):
method checkpoint_graph (line 237) | def checkpoint_graph(self, max_tries=60):
method _send_collectd_metrics (line 309) | def _send_collectd_metrics(self, answers, interval):
method _merge_status (line 361) | def _merge_status(self, nodename, status):
method _status_loop (line 387) | def _status_loop(self):
method status (line 422) | def status(self, timestamp, **kwargs):
method start_status_monitor (line 442) | def start_status_monitor(self):
method stop_status_monitor (line 451) | def stop_status_monitor(self):
method start (line 459) | def start(self):
method stop (line 462) | def stop(self):
class MgmtbusSlaveHub (line 466) | class MgmtbusSlaveHub(object):
method __init__ (line 477) | def __init__(self, config, comm_class, comm_config):
method request_log_channel (line 484) | def request_log_channel(self):
method send_status (line 491) | def send_status(self, params):
method request_chassis_rpc_channel (line 499) | def request_chassis_rpc_channel(self, chassis):
method request_channel (line 510) | def request_channel(self, node):
method add_failure_listener (line 541) | def add_failure_listener(self, f):
method send_master_rpc (line 544) | def send_master_rpc(self, command, params=None, timeout=None):
method start (line 552) | def start(self):
method stop (line 556) | def stop(self):
function master_factory (line 560) | def master_factory(config, comm_class, comm_config, nodes, num_chassis):
function slave_hub_factory (line 584) | def slave_hub_factory(config, comm_class, comm_config):
FILE: minemeld/packages/gdns/dig.py
class Dig (line 11) | class Dig(object):
method __init__ (line 78) | def __init__(self, hub=None, **kwargs):
method __repr__ (line 89) | def __repr__(self):
method _on_fork (line 95) | def _on_fork(self):
method close (line 102) | def close(self):
method query (line 108) | def query(self, name, dnsclass, type_):
method parse_txt_reply (line 127) | def parse_txt_reply(self, reply):
FILE: minemeld/packages/gdns/dnshelper.c
function PyObject (line 20) | static PyObject*
function gevent_append_addr (line 44) | static int
function PyObject (line 59) | static PyObject*
function PyObject (line 91) | static PyObject *
function gevent_make_sockaddr (line 132) | static int
FILE: minemeld/packages/gevent_openssl/SSL.py
class Connection (line 15) | class Connection(object):
method __init__ (line 21) | def __init__(self, context, sock):
method __getattr__ (line 26) | def __getattr__(self, attr):
method __iowait (line 29) | def __iowait(self, io_func, *args, **kwargs):
method accept (line 40) | def accept(self):
method do_handshake (line 44) | def do_handshake(self):
method connect (line 51) | def connect(self, *args, **kwargs):
method send (line 54) | def send(self, data, flags=0):
method sendall (line 57) | def sendall(self, data, flags=0):
method __send (line 66) | def __send(self, send_method, data, flags=0):
method recv (line 76) | def recv(self, bufsiz, flags=0):
method shutdown (line 91) | def shutdown(self):
FILE: minemeld/packages/gevent_openssl/__init__.py
function monkey_patch (line 30) | def monkey_patch():
FILE: minemeld/packages/ise/ers.py
class IseErsRequest (line 44) | class IseErsRequest:
method __init__ (line 45) | def __init__(self, name=None):
method raise_for_status (line 59) | def raise_for_status(self):
class IseErsError (line 67) | class IseErsError(Exception):
class IseErs (line 71) | class IseErs:
method __init__ (line 72) | def __init__(self,
method _request (line 94) | def _request(self,
method _set_attributes (line 114) | def _set_attributes(self, r):
method sgts_ips_map (line 153) | def sgts_ips_map(self):
method sgt (line 202) | def sgt(self,
method sgmapping (line 250) | def sgmapping(self,
FILE: minemeld/packages/panforest/forest.py
class PanForestError (line 30) | class PanForestError(Exception):
method __init__ (line 31) | def __init__(self, msg):
method __str__ (line 34) | def __str__(self):
class PanForest (line 40) | class PanForest(object):
method __init__ (line 41) | def __init__(self,
method __iter__ (line 55) | def __iter__(self):
method sleep (line 58) | def sleep(self, t):
method follow (line 61) | def follow(self):
method tail (line 145) | def tail(self, lines):
method _log_get (line 160) | def _log_get(self, nlogs=None, skip=None, filter=None):
method _sleeper (line 180) | def _sleeper(self):
method _xml_python (line 195) | def _xml_python(elem, path=None):
method _log_count (line 204) | def _log_count(self, obj):
method _log_seqno (line 218) | def _log_seqno(self, obj):
method _log_entry (line 228) | def _log_entry(obj, key):
method _filter (line 234) | def _filter(self, seqno):
FILE: minemeld/run/cacert_merge.py
function create_default_context (line 26) | def create_default_context(cafile, cadata):
function main (line 40) | def main():
function verify_cafile (line 136) | def verify_cafile(cafile=None, cadata=None):
FILE: minemeld/run/config.py
class MineMeldConfigChange (line 71) | class MineMeldConfigChange(_ConfigChange):
method __new__ (line 72) | def __new__(_cls, nodename, nodeclass, change, detail=None):
class MineMeldConfig (line 82) | class MineMeldConfig(_Config):
method as_nset (line 83) | def as_nset(self):
method compute_changes (line 94) | def compute_changes(self, oconfig):
method from_dict (line 177) | def from_dict(cls, dconfig=None):
function _load_node_prototype (line 220) | def _load_node_prototype(protoname, paths):
function _load_config_from_file (line 254) | def _load_config_from_file(f):
function _load_and_validate_config_from_file (line 264) | def _load_and_validate_config_from_file(path):
function _destroy_node (line 295) | def _destroy_node(change, installed_nodes=None, installed_nodes_gcs=None):
function _destroy_old_nodes (line 343) | def _destroy_old_nodes(config):
function _load_config_from_dir (line 372) | def _load_config_from_dir(path):
function _detect_cycles (line 426) | def _detect_cycles(nodes):
function resolve_prototypes (line 466) | def resolve_prototypes(config):
function validate_config (line 521) | def validate_config(config):
function load_config (line 565) | def load_config(config_path):
FILE: minemeld/run/console.py
function _send_cmd (line 34) | def _send_cmd(ctx, target, command, params=None, source=True):
function _print_json (line 47) | def _print_json(obj):
function cli (line 60) | def cli(ctx, verbose, comm_class):
function length (line 91) | def length(ctx, target):
function hup (line 103) | def hup(ctx, target):
function status (line 116) | def status(ctx, target):
function mm_signal (line 131) | def mm_signal(ctx, signal, target):
function query (line 147) | def query(ctx, query, from_counter, from_timestamp, num_lines, query_uuid):
function main (line 170) | def main():
FILE: minemeld/run/extgit.py
function _parse_args (line 25) | def _parse_args():
function main (line 61) | def main():
FILE: minemeld/run/freeze.py
function _parse_args (line 23) | def _parse_args():
function main (line 49) | def main():
FILE: minemeld/run/launcher.py
function _run_chassis (line 41) | def _run_chassis(fabricconfig, mgmtbusconfig, fts):
function _check_disk_space (line 77) | def _check_disk_space(num_nodes):
function _parse_args (line 99) | def _parse_args():
function _setup_environment (line 139) | def _setup_environment(config):
function main (line 150) | def main():
FILE: minemeld/run/restore.py
class BFile (line 24) | class BFile(object):
method __init__ (line 25) | def __init__(self, zip_path, type_, extracted_path=None, target_path=N...
method __repr__ (line 31) | def __repr__(self):
function _parse_args (line 40) | def _parse_args():
class ContextManagerStack (line 87) | class ContextManagerStack(object):
method __init__ (line 88) | def __init__(self):
method enter (line 91) | def enter(self, cm):
method __enter__ (line 97) | def __enter__(self):
method __exit__ (line 100) | def __exit__(self, *exc_info):
function handle_minemeld_engine (line 107) | def handle_minemeld_engine(supervisor_url):
function extract_file (line 181) | def extract_file(backup_id, bfile, efile, configuration_path, prototypes...
function backup_file (line 223) | def backup_file(old_file_path):
function restore_file (line 245) | def restore_file(f):
function _list_of_configuration_files (line 259) | def _list_of_configuration_files(bfile, flist):
function _list_of_prototypes_files (line 280) | def _list_of_prototypes_files(bfile, flist):
function _list_of_certificates_files (line 295) | def _list_of_certificates_files(bfile, flist):
function _list_of_feeds_aaa_files (line 311) | def _list_of_feeds_aaa_files(faaf, bfile, flist):
function _reload_candidate_config (line 319) | def _reload_candidate_config(supervisor_url):
function main (line 358) | def main():
FILE: minemeld/startupplanner.py
class CheckpointNodes (line 13) | class CheckpointNodes(object):
method __init__ (line 14) | def __init__(self):
function _build_graph (line 19) | def _build_graph(config):
function _plan_subgraph (line 34) | def _plan_subgraph(sg, config, state_info):
function plan (line 164) | def plan(config, state_info):
FILE: minemeld/supervisord/listener.py
function _handle_event (line 13) | def _handle_event(SR, engine_process_name, hdrs, payload):
function main (line 43) | def main():
FILE: minemeld/traced/main.py
function _parse_args (line 42) | def _parse_args():
function _ioloop_failure (line 65) | def _ioloop_failure(event):
function main (line 70) | def main():
FILE: minemeld/traced/purge.py
function _parse_args (line 16) | def _parse_args():
function stop_minemeld_traced (line 40) | def stop_minemeld_traced(supervisor_url):
function start_minemeld_traced (line 91) | def start_minemeld_traced(supervisor_url):
function main (line 105) | def main():
FILE: minemeld/traced/queryprocessor.py
class Query (line 41) | class Query(gevent.Greenlet):
method __init__ (line 42) | def __init__(self, store, query, timestamp, counter,
method _parse_query (line 62) | def _parse_query(self, query):
method _check_query (line 107) | def _check_query(self, log):
method _core_run (line 114) | def _core_run(self):
method _run (line 153) | def _run(self):
class QueryProcessor (line 163) | class QueryProcessor(object):
method __init__ (line 164) | def __init__(self, comm, store, config=None):
method _query_finished (line 183) | def _query_finished(self, gquery):
method query (line 199) | def query(self, uuid, query, timestamp=None, counter=None, num_lines=N...
method kill_query (line 244) | def kill_query(self, uuid):
method stop (line 255) | def stop(self):
FILE: minemeld/traced/storage.py
class TableNotFound (line 40) | class TableNotFound(Exception):
class Table (line 44) | class Table(object):
method __init__ (line 45) | def __init__(self, name, create_if_missing=True):
method add_reference (line 85) | def add_reference(self, refid):
method remove_reference (line 88) | def remove_reference(self, refid):
method ref_count (line 101) | def ref_count(self):
method put (line 104) | def put(self, key, value):
method backwards_iterator (line 115) | def backwards_iterator(self, timestamp, counter):
method close (line 124) | def close(self):
method oldest_table (line 129) | def oldest_table():
function _lock_current_tables (line 151) | def _lock_current_tables():
class Store (line 169) | class Store(object):
method __init__ (line 170) | def __init__(self, config=None):
method _open_table (line 186) | def _open_table(self, name, create_if_missing):
method _close_table (line 192) | def _close_table(self, table):
method _add_table (line 196) | def _add_table(self, name, priority, create_if_missing=True):
method _get_table (line 218) | def _get_table(self, day, ref, create_if_missing=True):
method _process_queue_element (line 234) | def _process_queue_element(self, name, ftable, create_if_missing):
method _process_queue (line 269) | def _process_queue(self):
method _release (line 298) | def _release(self, table, ref):
method write (line 303) | def write(self, timestamp, log):
method iterate_backwards (line 321) | def iterate_backwards(self, ref, timestamp, counter):
method release_all (line 385) | def release_all(self, ref):
method stop (line 396) | def stop(self):
FILE: minemeld/traced/writer.py
class DiskSpaceMonitor (line 29) | class DiskSpaceMonitor(gevent.Greenlet):
method __init__ (line 30) | def __init__(self, threshold, low_disk):
method _run (line 36) | def _run(self):
class Writer (line 55) | class Writer(object):
method __init__ (line 56) | def __init__(self, comm, store, topic, config):
method log (line 76) | def log(self, timestamp, **kwargs):
method stop (line 85) | def stop(self):
FILE: tests/comm_mock.py
class MockComm (line 19) | class MockComm(object):
method __init__ (line 20) | def __init__(self, config):
method request_sub_channel (line 26) | def request_sub_channel(self, topic, obj=None, allowed_methods=None, n...
method request_rpc_server_channel (line 34) | def request_rpc_server_channel(self, name, obj=None, allowed_methods=[],
function comm_factory (line 44) | def comm_factory(config):
FILE: tests/integration/basic/test.py
function get_full_config (line 21) | def get_full_config(mmurl, username, password):
function delete_node (line 32) | def delete_node(nodeid, version, mmurl, username, password):
function create_node (line 42) | def create_node(version, nodename, prototype, inputs, output, mmurl, use...
function commit_and_restart (line 63) | def commit_and_restart(mmurl, username, password):
function delete_config (line 87) | def delete_config(mmurl, username, password):
function create_config (line 110) | def create_config(mmurl, username, password):
function wait_for_restart (line 194) | def wait_for_restart(mmurl, username, password):
function push_indicators (line 218) | def push_indicators(mmurl, username, password):
function remove_timestamps (line 307) | def remove_timestamps(s):
function check_feeds (line 315) | def check_feeds(mmurl):
function main (line 352) | def main():
FILE: tests/panos_mock.py
class PanXapiMock (line 27) | class PanXapiMock(object):
method __init__ (line 28) | def __init__(self, **kwargs):
method _parse_answer (line 34) | def _parse_answer(self, cmd, arg, counter):
method get (line 53) | def get(self, **kwargs):
method show (line 63) | def show(self, **kwargs):
method op (line 73) | def op(self, **kwargs):
method user_id (line 83) | def user_id(self, **kwargs):
function factory (line 91) | def factory(**kwargs):
FILE: tests/st_profile.py
function queries (line 27) | def queries(st):
FILE: tests/test_comm_amqp.py
class MineMeldCommAMQP (line 23) | class MineMeldCommAMQP(unittest.TestCase):
method test_01_rpc (line 24) | def test_01_rpc(self):
method test_02_pubsub (line 40) | def test_02_pubsub(self):
method test_03_rpc_fanout (line 61) | def test_03_rpc_fanout(self):
FILE: tests/test_flask_aaa.py
function _authorization_header (line 53) | def _authorization_header(username, password):
class MineMeldFlaskAAATests (line 57) | class MineMeldFlaskAAATests(unittest.TestCase):
method setUp (line 58) | def setUp(self):
method tearDown (line 71) | def tearDown(self):
method _taxii_discovery_request (line 77) | def _taxii_discovery_request(self, username=None, password=None):
method _taxii_collection_request (line 93) | def _taxii_collection_request(self, username=None, password=None):
method _taxii_poll_request (line 109) | def _taxii_poll_request(self, collection, username=None, password=None):
method _num_collections (line 125) | def _num_collections(self, resp):
method test_feeds_auth_disabled (line 140) | def test_feeds_auth_disabled(self, mmmastermock, configmock, configini...
method test_feeds_single_tag (line 186) | def test_feeds_single_tag(self, mmmastermock, configmock, configinitmo...
method test_feeds_two_tags (line 245) | def test_feeds_two_tags(self, mmmastermock, configmock, configinitmock):
method test_feeds_two_and_two (line 304) | def test_feeds_two_and_two(self, mmmastermock, configmock, configinitm...
method test_feeds_any (line 363) | def test_feeds_any(self, mmmastermock, configmock, configinitmock):
method test_feeds_anonymous (line 422) | def test_feeds_anonymous(self, mmmastermock, configmock, configinitmock):
method test_feeds_anonymous_2 (line 481) | def test_feeds_anonymous_2(self, mmmastermock, configmock, configinitm...
method test_feeds_no_tags (line 540) | def test_feeds_no_tags(self, mmmastermock, configmock, configinitmock):
method test_feeds_no_user_tags (line 595) | def test_feeds_no_user_tags(self, mmmastermock, configmock, configinit...
method test_feeds_malformed (line 651) | def test_feeds_malformed(self, mmmastermock, configmock, configinitmock):
method test_taxii_auth_disabled (line 705) | def test_taxii_auth_disabled(self, gtfmock1, gtfmock2, configmock, con...
method test_taxii_services_tag (line 777) | def test_taxii_services_tag(self, gtfmock1, gtfmock2, configmock, conf...
method test_taxii_anonymous (line 854) | def test_taxii_anonymous(self, gtfmock1, gtfmock2, configmock, configi...
method test_taxii_any (line 932) | def test_taxii_any(self, gtfmock1, gtfmock2, configmock, configinitmock):
method test_taxii_any_anonymous (line 1010) | def test_taxii_any_anonymous(self, gtfmock1, gtfmock2, configmock, con...
method test_taxiipoll_single_tag (line 1088) | def test_taxiipoll_single_tag(self, gtfmock, configmock, configinitmock):
method test_taxiipolll_two_tags (line 1141) | def test_taxiipolll_two_tags(self, gtfmock, configmock, configinitmock):
method test_taxiipoll_two_and_two (line 1194) | def test_taxiipoll_two_and_two(self, gtfmock, configmock, configinitmo...
method test_taxiipoll_any (line 1247) | def test_taxiipoll_any(self, gtfmock, configmock, configinitmock):
method test_taxiipoll_anonymous (line 1300) | def test_taxiipoll_anonymous(self, gtfmock, configmock, configinitmock):
method test_taxiipoll_anonymous_2 (line 1353) | def test_taxiipoll_anonymous_2(self, gtfmock, configmock, configinitmo...
FILE: tests/test_ft_autofocus.py
function logical_millisec (line 43) | def logical_millisec(*args):
function gevent_event_mock_factory (line 47) | def gevent_event_mock_factory():
class MineMeldAutofocusFTTests (line 54) | class MineMeldAutofocusFTTests(unittest.TestCase):
method setUp (line 55) | def setUp(self):
method tearDown (line 61) | def tearDown(self):
method test_type_of_indicators (line 72) | def test_type_of_indicators(self, um_mock, sleep_mock, event_mock,
FILE: tests/test_ft_base.py
class MineMeldFTBaseTests (line 28) | class MineMeldFTBaseTests(unittest.TestCase):
method test_init (line 31) | def test_init(self, configure_mock):
method test_connect_io (line 47) | def test_connect_io(self):
method test_rpc (line 96) | def test_rpc(self):
method test_emit (line 141) | def test_emit(self):
method test_emit_filtered (line 195) | def test_emit_filtered(self):
method test_full_trace (line 267) | def test_full_trace(self):
FILE: tests/test_ft_basepoller.py
function logical_millisec (line 42) | def logical_millisec(*args):
function gevent_event_mock_factory (line 46) | def gevent_event_mock_factory():
class DeltaFeed (line 53) | class DeltaFeed(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 54) | def __init__(self, name, chassis):
method _build_iterator (line 70) | def _build_iterator(self, now):
method _process_item (line 79) | def _process_item(self, item):
class RollingFeed (line 83) | class RollingFeed(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 84) | def __init__(self, name, chassis):
method _build_iterator (line 100) | def _build_iterator(self, now):
method _process_item (line 109) | def _process_item(self, item):
class RollingFeedFirst (line 113) | class RollingFeedFirst(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 114) | def __init__(self, name, chassis):
method _build_iterator (line 133) | def _build_iterator(self, now):
method _process_item (line 142) | def _process_item(self, item):
class RollingFeedFirst2 (line 146) | class RollingFeedFirst2(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 147) | def __init__(self, name, chassis):
method _build_iterator (line 166) | def _build_iterator(self, now):
method _process_item (line 175) | def _process_item(self, item):
class PermanentFeed (line 179) | class PermanentFeed(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 180) | def __init__(self, name, chassis):
method _build_iterator (line 196) | def _build_iterator(self, now):
method _process_item (line 205) | def _process_item(self, item):
class SuperPermanentFeed (line 209) | class SuperPermanentFeed(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 210) | def __init__(self, name, chassis):
method _build_iterator (line 227) | def _build_iterator(self, now):
method _process_item (line 236) | def _process_item(self, item):
class PermanentFeedWithType (line 240) | class PermanentFeedWithType(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 241) | def __init__(self, name, chassis):
method _build_iterator (line 258) | def _build_iterator(self, now):
method _process_item (line 267) | def _process_item(self, item):
class PermanentFeedWithTypeAggregated (line 272) | class PermanentFeedWithTypeAggregated(minemeld.ft.basepoller.BasePollerFT):
method __init__ (line 273) | def __init__(self, name, chassis):
method _build_iterator (line 291) | def _build_iterator(self, now):
method _process_item (line 300) | def _process_item(self, item):
class DeltaFeedWithTypeAggregatedFaulty (line 305) | class DeltaFeedWithTypeAggregatedFaulty(minemeld.ft.basepoller.BasePolle...
method __init__ (line 306) | def __init__(self, name, chassis):
method _iterator (line 328) | def _iterator(self, iterator):
method _build_iterator (line 333) | def _build_iterator(self, now):
method _process_item (line 351) | def _process_item(self, item):
class MineMeldFTBasePollerTests (line 356) | class MineMeldFTBasePollerTests(unittest.TestCase):
method setUp (line 357) | def setUp(self):
method tearDown (line 363) | def tearDown(self):
method test_delta_feed (line 374) | def test_delta_feed(self, um_mock, event_mock, sleep_mock, spawnl_mock...
method test_rolling_feed (line 456) | def test_rolling_feed(self, um_mock, event_mock, sleep_mock,
method test_rolling_feed_first (line 542) | def test_rolling_feed_first(self, um_mock, event_mock, sleep_mock,
method test_rolling_feed_first2 (line 634) | def test_rolling_feed_first2(self, um_mock, event_mock, sleep_mock,
method test_permanent_feed (line 771) | def test_permanent_feed(self, um_mock, event_mock,
method test_superpermanent_feed (line 857) | def test_superpermanent_feed(self, um_mock, event_mock,
method test_drop_old_ops (line 928) | def test_drop_old_ops(self, um_mock, event_mock, sleep_mock, spawnl_mo...
method test_permanentwithtype_feed (line 977) | def test_permanentwithtype_feed(self, um_mock, event_mock,
method test_bptable_1 (line 1063) | def test_bptable_1(self, um_mock, event_mock,
method test_bptable_2 (line 1086) | def test_bptable_2(self, um_mock, event_mock,
method test_bptable_3 (line 1103) | def test_bptable_3(self, um_mock, event_mock,
method test_bptable_4 (line 1118) | def test_bptable_4(self, um_mock, event_mock,
method test_bptable_5 (line 1133) | def test_bptable_5(self, um_mock, event_mock,
method test_bptable_6 (line 1147) | def test_bptable_6(self, um_mock, event_mock,
method test_bptable_7 (line 1162) | def test_bptable_7(self, um_mock, event_mock,
method test_bptable_8 (line 1178) | def test_bptable_8(self, um_mock, event_mock,
method test_permanentwithtype_feed_agg (line 1197) | def test_permanentwithtype_feed_agg(self, um_mock, event_mock,
method test_permanentwithtype_feed_agg2 (line 1283) | def test_permanentwithtype_feed_agg2(self, um_mock, event_mock,
FILE: tests/test_ft_boolexpr.py
class ExprBuilder (line 33) | class ExprBuilder(minemeld.ft.condition.BoolExprListener):
method __init__ (line 34) | def __init__(self):
method exitExpression (line 39) | def exitExpression(self, ctx):
method exitComparator (line 42) | def exitComparator(self, ctx):
method exitValue (line 57) | def exitValue(self, ctx):
function _parse_string (line 70) | def _parse_string(s):
function _eval_expression (line 85) | def _eval_expression(eb, i):
class MineMeldFTBaseTests (line 99) | class MineMeldFTBaseTests(unittest.TestCase):
method test_simple (line 100) | def test_simple(self):
method test_func (line 106) | def test_func(self):
method test_eval (line 113) | def test_eval(self):
FILE: tests/test_ft_dag.py
function logical_millisec (line 50) | def logical_millisec(*args):
function gevent_event_mock_factory (line 54) | def gevent_event_mock_factory():
function device_pusher_mock_factory (line 61) | def device_pusher_mock_factory(device, prefix, watermark, attributes, pe...
class MineMeldFTDagPusherTests (line 71) | class MineMeldFTDagPusherTests(unittest.TestCase):
method setUp (line 72) | def setUp(self):
method tearDown (line 83) | def tearDown(self):
method test_device_list_load (line 102) | def test_device_list_load(self, dp_mock, timegm_mock, event_mock, hw_m...
method test_uw (line 212) | def test_uw(self, dp_mock, timegm_mock, event_mock,
method test_uinvalid (line 300) | def test_uinvalid(self, dp_mock, timegm_mock, event_mock,
method test_unicast1 (line 366) | def test_unicast1(self, dp_mock, timegm_mock, event_mock,
method test_unicast2 (line 454) | def test_unicast2(self, dp_mock, timegm_mock, event_mock,
method test_devicepusher_dag_message (line 536) | def test_devicepusher_dag_message(self, panxapi_mock):
method test_devicepusher_tags_from_value (line 555) | def test_devicepusher_tags_from_value(self, panxapi_mock):
method test_devicepusher_get_all_registered_ips (line 574) | def test_devicepusher_get_all_registered_ips(self, panxapi_mock):
method test_devicepusher_push (line 588) | def test_devicepusher_push(self, panxapi_mock):
method test_devicepusher_init_resync (line 604) | def test_devicepusher_init_resync(self, panxapi_mock):
FILE: tests/test_ft_ipop.py
function check_for_rpc (line 43) | def check_for_rpc(call_args_list, check_list, all_here=False):
class MineMeldFTIPOpTests (line 96) | class MineMeldFTIPOpTests(unittest.TestCase):
method setUp (line 97) | def setUp(self):
method tearDown (line 108) | def tearDown(self):
method test_calc_ipranges (line 119) | def test_calc_ipranges(self):
method test_uwl (line 262) | def test_uwl(self):
method test_uwl2 (line 339) | def test_uwl2(self):
method test_uwl3 (line 423) | def test_uwl3(self):
method test_overlap_by_one (line 536) | def test_overlap_by_one(self):
method test_overlap_by_lastrange (line 610) | def test_overlap_by_lastrange(self):
method test_3overlaps (line 680) | def test_3overlaps(self):
method test_2overlaps (line 784) | def test_2overlaps(self):
method test_attr_override (line 882) | def test_attr_override(self):
method test_uw (line 943) | def test_uw(self):
method test_2uw (line 1009) | def test_2uw(self):
method test_uw_wrongtype (line 1086) | def test_uw_wrongtype(self):
method test_updated_indicator (line 1153) | def test_updated_indicator(self):
method test_stress_1 (line 1223) | def test_stress_1(self):
method test_stress_2 (line 1294) | def test_stress_2(self):
FILE: tests/test_ft_local.py
function logical_millisec (line 45) | def logical_millisec(*args):
function gevent_event_mock_factory (line 49) | def gevent_event_mock_factory():
class MineMeldYamlFTTests (line 56) | class MineMeldYamlFTTests(unittest.TestCase):
method setUp (line 57) | def setUp(self):
method tearDown (line 68) | def tearDown(self):
method test_yaml (line 84) | def test_yaml(self, um_mock, sleep_mock, event_mock,
FILE: tests/test_ft_logstash.py
class MineMeldFTLogstashOutputTests (line 29) | class MineMeldFTLogstashOutputTests(unittest.TestCase):
method test_uw (line 30) | def test_uw(self):
FILE: tests/test_ft_op.py
function check_for_rpc (line 41) | def check_for_rpc(call_args_list, check_list, all_here=False, offset=0):
class MineMeldFTOpTests (line 95) | class MineMeldFTOpTests(unittest.TestCase):
method setUp (line 96) | def setUp(self):
method tearDown (line 102) | def tearDown(self):
method test_aggregate_2u (line 108) | def test_aggregate_2u(self):
method test_aggregate_uwl (line 154) | def test_aggregate_uwl(self):
method test_aggregate_2uw (line 200) | def test_aggregate_2uw(self):
method test_aggregate_2u2w (line 245) | def test_aggregate_2u2w(self):
method test_aggregate_u2w_difftypes (line 302) | def test_aggregate_u2w_difftypes(self):
method test_aggregate_uwlwl (line 360) | def test_aggregate_uwlwl(self):
method test_infilters (line 420) | def test_infilters(self):
method test_infilters_2u (line 471) | def test_infilters_2u(self):
method test_attr_override (line 531) | def test_attr_override(self):
method test_get_all (line 593) | def test_get_all(self):
method test_get_range (line 673) | def test_get_range(self):
FILE: tests/test_ft_redis.py
class MineMeldFTRedisTests (line 33) | class MineMeldFTRedisTests(unittest.TestCase):
method setUp (line 34) | def setUp(self):
method tearDown (line 38) | def tearDown(self):
method test_init (line 42) | def test_init(self):
method test_connect_io (line 57) | def test_connect_io(self):
method test_uw (line 108) | def test_uw(self):
method test_stats (line 145) | def test_stats(self):
method test_store_value (line 186) | def test_store_value(self):
method test_store_value_overflow (line 227) | def test_store_value_overflow(self):
FILE: tests/test_ft_st.py
class MineMeldFTSTTests (line 35) | class MineMeldFTSTTests(unittest.TestCase):
method setUp (line 36) | def setUp(self):
method tearDown (line 42) | def tearDown(self):
method test_add_delete (line 48) | def test_add_delete(self):
method test_query_endpoints_forward (line 58) | def test_query_endpoints_forward(self):
method test_query_endpoints_reverse (line 79) | def test_query_endpoints_reverse(self):
method test_basic_cover (line 100) | def test_basic_cover(self):
method test_cover_overlap (line 120) | def test_cover_overlap(self):
method test_cover_overlap2 (line 166) | def test_cover_overlap2(self):
method _random_map (line 188) | def _random_map(self, nbits=10, nintervals=1000):
method test_random_map_fast (line 226) | def test_random_map_fast(self):
method test_random_map_fast2 (line 230) | def test_random_map_fast2(self):
method test_255 (line 233) | def test_255(self):
method test_stress_0 (line 242) | def test_stress_0(self):
method test_stress_1 (line 277) | def test_stress_1(self):
FILE: tests/test_ft_syslog.py
function check_for_rpc (line 36) | def check_for_rpc(call_args_list, check_list, all_here=False):
class MineMeldFTSyslogMatcherests (line 89) | class MineMeldFTSyslogMatcherests(unittest.TestCase):
method setUp (line 90) | def setUp(self):
method tearDown (line 106) | def tearDown(self):
method test_handle_ip_01 (line 123) | def test_handle_ip_01(self, spawnl_mock):
method test_handle_ip_02 (line 183) | def test_handle_ip_02(self, spawnl_mock):
method test_handle_ip_03 (line 240) | def test_handle_ip_03(self, spawnl_mock):
method test_handle_url_01 (line 283) | def test_handle_url_01(self, spawnl_mock):
method test_handle_url_02 (line 343) | def test_handle_url_02(self, spawnl_mock):
method test_logstash_url (line 402) | def test_logstash_url(self, socket_socket, spawnl_mock):
method test_logstash_ip (line 453) | def test_logstash_ip(self, socket_socket, spawnl_mock):
method test_logstash_event_tags (line 501) | def test_logstash_event_tags(self, socket_socket, spawnl_mock):
FILE: tests/test_ft_table.py
class MineMeldFTTableTests (line 34) | class MineMeldFTTableTests(unittest.TestCase):
method setUp (line 35) | def setUp(self):
method tearDown (line 41) | def tearDown(self):
method test_truncate (line 47) | def test_truncate(self):
method test_insert (line 62) | def test_insert(self):
method test_index_query (line 74) | def test_index_query(self):
method test_index_query_2 (line 94) | def test_index_query_2(self):
method test_index_query_3 (line 119) | def test_index_query_3(self):
method test_query (line 148) | def test_query(self):
method test_exists (line 164) | def test_exists(self):
method test_not_exists (line 181) | def test_not_exists(self):
method test_update (line 195) | def test_update(self):
method test_random (line 214) | def test_random(self):
method test_write (line 292) | def test_write(self):
FILE: tests/test_ft_taxii.py
class MockTaxiiContentBlock (line 47) | class MockTaxiiContentBlock(object):
method __init__ (line 48) | def __init__(self, stix_xml):
class MineMeldFTTaxiiTests (line 57) | class MineMeldFTTaxiiTests(unittest.TestCase):
method test_taxiiclient_parse (line 59) | def test_taxiiclient_parse(self, glet_mock):
method test_datafeed_init (line 133) | def test_datafeed_init(self, glet_mock, SR_mock):
method test_datafeed_update_ip (line 150) | def test_datafeed_update_ip(self, glet_mock, SR_mock):
method test_datafeed_update_domain (line 319) | def test_datafeed_update_domain(self, glet_mock, SR_mock):
method test_datafeed_update_url (line 376) | def test_datafeed_update_url(self, glet_mock, SR_mock):
method test_datafeed_unicode_url (line 433) | def test_datafeed_unicode_url(self, glet_mock, SR_mock):
method test_datafeed_overflow (line 490) | def test_datafeed_overflow(self, glet_mock, SR_mock):
method test_datafeed_update_hash (line 567) | def test_datafeed_update_hash(self, glet_mock, SR_mock):
FILE: tests/test_run_config.py
class MineMeldRunConfigTests (line 33) | class MineMeldRunConfigTests(unittest.TestCase):
method test_defaults_from_file (line 34) | def test_defaults_from_file(self):
method test_prototype_1 (line 46) | def test_prototype_1(self):
method test_validate_config_1 (line 57) | def test_validate_config_1(self):
method test_validate_config_2 (line 75) | def test_validate_config_2(self):
method test_validate_config_3 (line 93) | def test_validate_config_3(self):
method test_validate_config_4 (line 120) | def test_validate_config_4(self):
FILE: tests/test_startupplanner.py
class MineMeldStartupPlanner (line 31) | class MineMeldStartupPlanner(unittest.TestCase):
method test_subgraphs_1 (line 32) | def test_subgraphs_1(self):
method test_new_miner (line 106) | def test_new_miner(self):
method test_removed_output (line 162) | def test_removed_output(self):
method test_added_chain (line 219) | def test_added_chain(self):
method test_invalid_chain_1 (line 293) | def test_invalid_chain_1(self):
method test_invalid_node_1 (line 381) | def test_invalid_node_1(self):
method test_invalid_node_2 (line 431) | def test_invalid_node_2(self):
method test_invalid_node_3 (line 481) | def test_invalid_node_3(self):
method test_existing_source_added (line 553) | def test_existing_source_added(self):
method test_non_existing_source_added (line 614) | def test_non_existing_source_added(self):
method test_non_source_existing_input_added (line 672) | def test_non_source_existing_input_added(self):
FILE: tests/test_traced_queryprocessor.py
class MineMeldTracedStorage (line 46) | class MineMeldTracedStorage(unittest.TestCase):
method setUp (line 47) | def setUp(self):
method tearDown (line 51) | def tearDown(self):
method test_query_1 (line 57) | def test_query_1(self, glet_mock, SR_mock):
method test_query_pos (line 91) | def test_query_pos(self, glet_mock, SR_mock):
method test_query_and (line 126) | def test_query_and(self, glet_mock, SR_mock):
method test_query_fs1 (line 164) | def test_query_fs1(self, glet_mock, SR_mock):
method test_query_fs2 (line 211) | def test_query_fs2(self, glet_mock, SR_mock):
method test_query_fs3 (line 258) | def test_query_fs3(self, glet_mock, SR_mock):
method test_query_fs4 (line 305) | def test_query_fs4(self, glet_mock, SR_mock):
method test_query_fs5 (line 352) | def test_query_fs5(self, glet_mock, SR_mock):
method test_query_wcard (line 399) | def test_query_wcard(self, glet_mock, SR_mock):
method test_query_empty (line 446) | def test_query_empty(self, glet_mock, SR_mock):
method test_queryprocessor_1 (line 477) | def test_queryprocessor_1(self, query_mock):
method test_queryprocessor_2 (line 517) | def test_queryprocessor_2(self, query_mock):
method test_queryprocessor_3 (line 558) | def test_queryprocessor_3(self, query_mock):
method test_queryprocessor_4 (line 593) | def test_queryprocessor_4(self, query_mock):
method test_queryprocessor_5 (line 623) | def test_queryprocessor_5(self, query_mock):
FILE: tests/test_traced_storage.py
class MineMeldTracedStorage (line 38) | class MineMeldTracedStorage(unittest.TestCase):
method setUp (line 39) | def setUp(self):
method tearDown (line 47) | def tearDown(self):
method test_table_constructor (line 55) | def test_table_constructor(self):
method test_table_write (line 73) | def test_table_write(self):
method test_table_references (line 90) | def test_table_references(self):
method test_table_oldest (line 109) | def test_table_oldest(self):
method test_store_simple (line 128) | def test_store_simple(self):
method test_store_write (line 134) | def test_store_write(self, table_mock):
method test_store_iterate_backwards (line 163) | def test_store_iterate_backwards(self, table_mock):
method test_store_iterate_backwards_2 (line 198) | def test_store_iterate_backwards_2(self, table_mock):
method test_store_iterate_backwards_empty (line 224) | def test_store_iterate_backwards_empty(self, table_mock):
method test_stress_1 (line 243) | def test_stress_1(self):
FILE: tests/test_traced_writer.py
class MineMeldTracedStorage (line 36) | class MineMeldTracedStorage(unittest.TestCase):
method test_writer (line 37) | def test_writer(self):
FILE: tests/traced_mock.py
function _get_clock (line 30) | def _get_clock():
class MockTable (line 38) | class MockTable(object):
method __init__ (line 39) | def __init__(self, name, create_if_missing=True):
method add_reference (line 51) | def add_reference(self, refid):
method remove_reference (line 54) | def remove_reference(self, refid):
method ref_count (line 61) | def ref_count(self):
method put (line 64) | def put(self, key, value):
method backwards_iterator (line 72) | def backwards_iterator(self, timestamp, counter):
method close (line 78) | def close(self):
method oldest_table (line 82) | def oldest_table():
function table_factory (line 90) | def table_factory(name, create_if_missing=True):
function table_cleanup (line 102) | def table_cleanup():
class MockStore (line 106) | class MockStore(object):
method __init__ (line 107) | def __init__(self, config=None):
method write (line 117) | def write(self, timestamp, log):
method iterate_backwards (line 125) | def iterate_backwards(self, ref, timestamp, counter):
method release_all (line 135) | def release_all(self, ref):
function store_factory (line 138) | def store_factory(config=None):
class MockQuery (line 143) | class MockQuery(gevent.Greenlet):
method __init__ (line 144) | def __init__(self, store, query, timestamp, counter,
method kill (line 158) | def kill(self):
method _run (line 162) | def _run(self):
class MockEQuery (line 167) | class MockEQuery(gevent.Greenlet):
method __init__ (line 168) | def __init__(self, store, query, timestamp, counter,
method kill (line 182) | def kill(self):
method _run (line 186) | def _run(self):
function query_factory (line 191) | def query_factory(store, query, timestamp, counter,
function query_cleanup (line 205) | def query_cleanup():
Condensed preview — 221 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,911K chars).
[
{
"path": ".circleci/config.yml",
"chars": 3293,
"preview": "version: 2.1\norbs:\n aws-s3: circleci/aws-s3@1.0.4\njobs:\n build-bionic:\n docker:\n - image: circleci/buildpack-d"
},
{
"path": ".gitignore",
"chars": 746,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\n"
},
{
"path": "AUTHORS",
"chars": 384,
"preview": "Luigi Mori <lmori@paloaltonetworks.com>\nKevin Steves <ksteves@paloaltonetworks.com>\nPhil Da Silva <pdasilva@paloaltonetw"
},
{
"path": "LICENSE",
"chars": 10173,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "NOTICE",
"chars": 153,
"preview": "MineMeld Core\nCopyright 2016 Palo Alto Networks\n\nThis product includes software developed at\nPalo Alto Networks Inc. (ht"
},
{
"path": "README.md",
"chars": 231,
"preview": "# minemeld-core\n\nThis repo contains the code for the engine and the API of MineMeld, an extensible Threat Intelligence p"
},
{
"path": "docs/Makefile",
"chars": 7417,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "docs/architecture.rst",
"chars": 2220,
"preview": "Architecture\n============\n\nProcessing graph\n----------------\n\nThe core processing engine of MineMeld is based on a Direc"
},
{
"path": "docs/conf.py",
"chars": 9574,
"preview": "# -*- coding: utf-8 -*-\n#\n# minemeld-core documentation build configuration file, created by\n# sphinx-quickstart on Thu "
},
{
"path": "docs/configapi.rst",
"chars": 5977,
"preview": "Configuration API\n=================\n\nConfiguration API can be used to change a temporary configuration. The temp\nconfigu"
},
{
"path": "docs/index.rst",
"chars": 545,
"preview": ".. MineMeld documentation master file, created by\n sphinx-quickstart on Thu Aug 6 14:14:33 2015.\n You can adapt thi"
},
{
"path": "docs/internals.rst",
"chars": 160,
"preview": "Internals\n=========\n\nminemeld.ft.table\n-------------------\n\n.. automodule:: minemeld.ft.table\n\n\nminemeld.ft.st\n---------"
},
{
"path": "docs/license.rst",
"chars": 789,
"preview": "LICENSE\n=======\n\nCopyright (c) 2015, Palo Alto Networks <techbizdev@paloaltonetworks.com>\n\nPermission to use, copy, modi"
},
{
"path": "docs/messages.rst",
"chars": 617,
"preview": "Messages\n========\n\nIntra-node protocol\n-------------------\n\nThe protocol used between nodes is super simple. There are 3"
},
{
"path": "docs/metricsapi.rst",
"chars": 1240,
"preview": "Metrics API\n===========\n\nMetrics API can be used to retrieve historical statistics of the system and\nMineMeld nodes.\n\nMe"
},
{
"path": "docs/nodeconfig.rst",
"chars": 9941,
"preview": "Node config\n===========\n\nThe set of config parameters supported by a node depends on the node class.\n\n.. note::\n This"
},
{
"path": "docs/schema-indicator-0-1.json",
"chars": 2553,
"preview": "{\n \"id\": \"https://www.paloaltonetworks.com/minemeld-indicator-schema-0-1#\",\n \"$schema\": \"http://json-schema.org/dr"
},
{
"path": "docs/schema.rst",
"chars": 125,
"preview": "Indicator value schema\n======================\n\n.. literalinclude:: schema-indicator-0-1.json\n :language: json\n :line"
},
{
"path": "docs/scripts.rst",
"chars": 3910,
"preview": "mm-run\n=========\n\nmm-run is a simple script that can be used as frontend to the minemeld library.\n\nUsage\n-----\n\n::\n\n "
},
{
"path": "docs/statusapi.rst",
"chars": 1143,
"preview": "Status API\n==========\n\nStatus API can be used to retrieve status information about minemeld core\nengine and the system.\n"
},
{
"path": "minemeld/__init__.py",
"chars": 78,
"preview": "\"\"\"\nminemeld\n========\n\nMineMeld core engine\n\"\"\"\n\n__version__ = '0.9.70.post5'\n"
},
{
"path": "minemeld/chassis.py",
"chars": 6761,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/collectd.py",
"chars": 2672,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/comm/__init__.py",
"chars": 268,
"preview": "from __future__ import absolute_import\n\nfrom .zmqredis import ZMQRedis\n\n\ndef factory(commclass, config):\n if commclas"
},
{
"path": "minemeld/comm/zmqredis.py",
"chars": 25492,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/extensions/__init__.py",
"chars": 31,
"preview": "from .manager import * # noqa\n"
},
{
"path": "minemeld/extensions/manager.py",
"chars": 9475,
"preview": "import sys\nimport os\nimport os.path\nimport json\nimport logging\nfrom email.parser import Parser\nfrom collections import n"
},
{
"path": "minemeld/fabric.py",
"chars": 3810,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/__init__.py",
"chars": 4591,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/flask/aaa.py",
"chars": 9549,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/aaaapi.py",
"chars": 6292,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/flask/cbfeed.py",
"chars": 86142,
"preview": "import json\nimport time\n\n\nclass CbFeed(object):\n def __init__(self, feedinfo, reports):\n self.data = {'feedinf"
},
{
"path": "minemeld/flask/config.py",
"chars": 5920,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/configapi.py",
"chars": 15263,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/configdataapi.py",
"chars": 13739,
"preview": "# Copyright 2015-present Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n#"
},
{
"path": "minemeld/flask/events.py",
"chars": 3261,
"preview": "import gevent\nimport gevent.queue\nimport redis\nimport werkzeug.local\nimport ujson as json\nfrom blinker import signal\n\nfr"
},
{
"path": "minemeld/flask/extensionsapi.py",
"chars": 14933,
"preview": "# Copyright 2015-2017 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/feedredis.py",
"chars": 18826,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/jobs.py",
"chars": 8097,
"preview": "# Copyright 2017 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/flask/jobsapi.py",
"chars": 1725,
"preview": "# Copyright 2015-2017 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/logger.py",
"chars": 2204,
"preview": "import logging\nimport json\n\nfrom flask import current_app\n\n# [2017-01-16 20:32:07 +0000] [15997] [INFO]\nLOG_FORMAT = '[%"
},
{
"path": "minemeld/flask/loginapi.py",
"chars": 1472,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/logsapi.py",
"chars": 1537,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/flask/main.py",
"chars": 45,
"preview": "from . import create_app\n\napp = create_app()\n"
},
{
"path": "minemeld/flask/metricsapi.py",
"chars": 7391,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/flask/mmrpc.py",
"chars": 2861,
"preview": "import json\n\nimport gevent\nimport gevent.event\nimport gevent.queue\nimport werkzeug.local\n\nfrom flask import g\n\nimport mi"
},
{
"path": "minemeld/flask/prototypeapi.py",
"chars": 10925,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/redisclient.py",
"chars": 897,
"preview": "import os\n\nimport redis\nimport werkzeug.local\n\nfrom flask import g\n\nfrom . import REDIS_URL\nfrom .logger import LOG\n\n\n__"
},
{
"path": "minemeld/flask/session.py",
"chars": 3861,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/sns.py",
"chars": 4035,
"preview": "import requests\nimport json\nimport os.path\nimport uuid\nimport minemeld\nfrom .logger import LOG\nfrom . import config\n\nTYP"
},
{
"path": "minemeld/flask/statusapi.py",
"chars": 14656,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/supervisorapi.py",
"chars": 4197,
"preview": "# Copyright 2015-2017 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/supervisorclient.py",
"chars": 909,
"preview": "from flask import g\n\nimport psutil # noqa\nimport xmlrpclib\nimport supervisor.xmlrpc\nimport werkzeug.local\n\nfrom . impor"
},
{
"path": "minemeld/flask/taxiicollmgmt.py",
"chars": 2695,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/taxiidiscovery.py",
"chars": 2860,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/taxiipoll.py",
"chars": 5328,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/taxiiutils.py",
"chars": 2700,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/tracedapi.py",
"chars": 3316,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/flask/utils.py",
"chars": 2100,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/flask/validateapi.py",
"chars": 2242,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/__init__.py",
"chars": 422,
"preview": "from minemeld.loader import load, MM_NODES_ENTRYPOINT\n\n\ndef factory(classname, name, chassis, config):\n node_class = "
},
{
"path": "minemeld/ft/actorbase.py",
"chars": 2187,
"preview": "import logging\nfrom collections import namedtuple\n\nimport gevent\nfrom gevent.queue import Queue\n\nfrom minemeld.ft.base i"
},
{
"path": "minemeld/ft/anomali.py",
"chars": 8165,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/auscert.py",
"chars": 2980,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/autofocus.py",
"chars": 4805,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/azure.py",
"chars": 8567,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/ft/bambenek.py",
"chars": 260,
"preview": "\"\"\"\nThis module implements a thin wrapper class around minemeld.ft.csv.CSVFT\nto mine Bambenek Consulting feeds\n\"\"\"\n\nfrom"
},
{
"path": "minemeld/ft/base.py",
"chars": 23490,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/ft/basepoller.py",
"chars": 31878,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/ft/cif.py",
"chars": 5716,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/ft/ciscoise.py",
"chars": 3813,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/cofense.py",
"chars": 7559,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/condition/BoolExpr.g4",
"chars": 764,
"preview": "grammar BoolExpr;\n\n@header {\n# flake8: noqa\n}\n\nbooleanExpression\n : expression comparator value\n ;\n\nexpression\n "
},
{
"path": "minemeld/ft/condition/BoolExpr.tokens",
"chars": 228,
"preview": "T__0=1\nT__1=2\nT__2=3\nT__3=4\nT__4=5\nT__5=6\nT__6=7\nT__7=8\nT__8=9\nT__9=10\nT__10=11\nT__11=12\nJAVASCRIPTIDENTIFIER=13\nSTRING="
},
{
"path": "minemeld/ft/condition/BoolExprLexer.py",
"chars": 4793,
"preview": "# Generated from BoolExpr.g4 by ANTLR 4.7.1\n# encoding: utf-8\nfrom __future__ import print_function\nfrom antlr4 import *"
},
{
"path": "minemeld/ft/condition/BoolExprLexer.tokens",
"chars": 228,
"preview": "T__0=1\nT__1=2\nT__2=3\nT__3=4\nT__4=5\nT__5=6\nT__6=7\nT__7=8\nT__8=9\nT__9=10\nT__10=11\nT__11=12\nJAVASCRIPTIDENTIFIER=13\nSTRING="
},
{
"path": "minemeld/ft/condition/BoolExprListener.py",
"chars": 1838,
"preview": "# Generated from BoolExpr.g4 by ANTLR 4.7.1\nfrom antlr4 import *\n\n# flake8: noqa\n\n\n# This class defines a complete liste"
},
{
"path": "minemeld/ft/condition/BoolExprParser.py",
"chars": 15721,
"preview": "# Generated from BoolExpr.g4 by ANTLR 4.7.1\n# encoding: utf-8\nfrom __future__ import print_function\nfrom antlr4 import *"
},
{
"path": "minemeld/ft/condition/__init__.py",
"chars": 196,
"preview": "from .BoolExprParser import BoolExprParser # noqa\nfrom .BoolExprLexer import BoolExprLexer # noqa\nfrom .BoolExprListen"
},
{
"path": "minemeld/ft/condition/interface.py",
"chars": 2809,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/csv.py",
"chars": 7910,
"preview": "# Copyright 2015-2020 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/ft/dag.py",
"chars": 20185,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/dag_ng.py",
"chars": 27061,
"preview": "# Copyright 2015-2019 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/ft/google.py",
"chars": 4704,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/http.py",
"chars": 8131,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/ipop.py",
"chars": 15103,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/json.py",
"chars": 8883,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/local.py",
"chars": 4022,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/localdb.py",
"chars": 4254,
"preview": "# Copyright 2017-present Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n#"
},
{
"path": "minemeld/ft/logstash.py",
"chars": 3457,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/mm.py",
"chars": 4089,
"preview": "# Copyright 2017-present Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n#"
},
{
"path": "minemeld/ft/o365.py",
"chars": 12465,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/op.py",
"chars": 7344,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/ft/panos.py",
"chars": 7809,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/phishme.py",
"chars": 14761,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/proofpoint.py",
"chars": 9617,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/recordedfuture.py",
"chars": 16537,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/redis.py",
"chars": 6792,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/st.py",
"chars": 7384,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/syslog.py",
"chars": 24861,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/table.py",
"chars": 17277,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/taxii.py",
"chars": 58146,
"preview": "# Copyright 2015-present Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n#"
},
{
"path": "minemeld/ft/taxii2.py",
"chars": 23442,
"preview": "# Copyright 2015-present Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n#"
},
{
"path": "minemeld/ft/test.py",
"chars": 3408,
"preview": "from __future__ import absolute_import\n\nimport logging\nimport gevent\n\nfrom . import base\nfrom .utils import utc_millisec"
},
{
"path": "minemeld/ft/threatconnect.py",
"chars": 14242,
"preview": "import logging\nimport hmac\nimport hashlib\nimport base64\nimport time\nimport requests\nimport pytz\nimport os\nimport yaml\nim"
},
{
"path": "minemeld/ft/threatq.py",
"chars": 5611,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/tmt.py",
"chars": 6759,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/utils.py",
"chars": 6146,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/visa.py",
"chars": 7115,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/vt.py",
"chars": 3425,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/ft/xmpp.py",
"chars": 15675,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/loader.py",
"chars": 3156,
"preview": "import logging\n\nimport pip\n\nfrom pkg_resources import working_set, WorkingSet\nfrom collections import namedtuple\n\nLOG = "
},
{
"path": "minemeld/mgmtbus.py",
"chars": 18883,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/packages/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "minemeld/packages/gdns/LICENSE",
"chars": 1289,
"preview": "Except when otherwise stated (look at the beginning of each file) the software\nand the documentation in this project are"
},
{
"path": "minemeld/packages/gdns/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "minemeld/packages/gdns/_ares.pyx",
"chars": 17874,
"preview": "# Copyright (c) 2011-2012 Denis Bilenko. See LICENSE for details.\n# 2016 - Modified by Palo Alto Networks\n\ncimport cares"
},
{
"path": "minemeld/packages/gdns/cares.pxd",
"chars": 3176,
"preview": "cdef extern from \"ares.h\":\n struct ares_options:\n int flags\n void* sock_state_cb\n void* sock_sta"
},
{
"path": "minemeld/packages/gdns/cares_ntop.h",
"chars": 74,
"preview": "#include <arpa/inet.h>\n#define ares_inet_ntop(w,x,y,z) inet_ntop(w,x,y,z)\n"
},
{
"path": "minemeld/packages/gdns/cares_pton.h",
"chars": 129,
"preview": "#include <arpa/inet.h>\n#define ares_inet_pton(x,y,z) inet_pton(x,y,z)\n#define ares_inet_net_pton(w,x,y,z) inet_net_pton("
},
{
"path": "minemeld/packages/gdns/dig.py",
"chars": 4336,
"preview": "# Based on resolver_ares.py from gevent\n# Copyright (c) 2011 Denis Bilenko. See LICENSE for details.\n\nfrom __future__ im"
},
{
"path": "minemeld/packages/gdns/dnshelper.c",
"chars": 3795,
"preview": "/* Copyright (c) 2011 Denis Bilenko. See LICENSE for details. */\n#include \"Python.h\"\n\n#ifdef HAVE_NETDB_H\n#include <netd"
},
{
"path": "minemeld/packages/gevent_openssl/COPYING",
"chars": 1498,
"preview": "Copyright (c) 2015, Menno Finlay-Smits\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or "
},
{
"path": "minemeld/packages/gevent_openssl/SSL.py",
"chars": 3084,
"preview": "\"\"\"gevent_openssl.SSL - gevent compatibility with OpenSSL.SSL (pyOpenSSL)\n\"\"\"\n\nimport logging\n\nimport OpenSSL.SSL\nfrom g"
},
{
"path": "minemeld/packages/gevent_openssl/__init__.py",
"chars": 744,
"preview": "\"\"\"gevent_openssl - gevent compatibility with pyOpenSSL.\n\nUsage\n-----\n\nInstead of importing OpenSSL directly, do so in t"
},
{
"path": "minemeld/packages/ise/__init__.py",
"chars": 158,
"preview": "import logging\n\nDEBUG1 = logging.DEBUG\nDEBUG2 = DEBUG1 - 1\nDEBUG3 = DEBUG2 - 1\n\nlogging.addLevelName(DEBUG2, 'DEBUG2')\nl"
},
{
"path": "minemeld/packages/ise/ers.py",
"chars": 9830,
"preview": "#\n# Copyright (c) 2016 Palo Alto Networks, Inc. <techbizdev@paloaltonetworks.com>\n#\n# Permission to use, copy, modify, a"
},
{
"path": "minemeld/packages/panforest/__init__.py",
"chars": 90,
"preview": "from . import forest\n\nPanForest = forest.PanForest\nPanForestError = forest.PanForestError\n"
},
{
"path": "minemeld/packages/panforest/forest.py",
"chars": 6748,
"preview": "#\n# Copyright (c) 2015 Palo Alto Networks, Inc. <techbizdev@paloaltonetworks.com>\n#\n# Permission to use, copy, modify, a"
},
{
"path": "minemeld/run/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "minemeld/run/cacert_merge.py",
"chars": 4292,
"preview": "# Copyright 2015-2017 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/run/config.py",
"chars": 16731,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/run/console.py",
"chars": 4268,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/run/extgit.py",
"chars": 2299,
"preview": "# Copyright 2019 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/run/freeze.py",
"chars": 1641,
"preview": "# Copyright 2017 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/run/launcher.py",
"chars": 8717,
"preview": "# Copyright 2015-2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "minemeld/run/restore.py",
"chars": 12615,
"preview": "#!/usr/bin/env python\n\nimport os\nimport signal\nimport time\nimport logging\nimport argparse\nimport xmlrpclib\nfrom zipfile "
},
{
"path": "minemeld/startupplanner.py",
"chars": 5887,
"preview": "import logging\nfrom operator import itemgetter\nfrom collections import defaultdict\n\nimport networkx as nx\n\nfrom minemeld"
},
{
"path": "minemeld/supervisord/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "minemeld/supervisord/listener.py",
"chars": 1538,
"preview": "import sys\nimport os\nimport logging\nimport time\n\nimport redis\nimport ujson\nfrom supervisor import childutils\n\nLOG = logg"
},
{
"path": "minemeld/traced/__init__.py",
"chars": 63,
"preview": "from minemeld.traced.queryprocessor import QUERY_QUEUE # noqa\n"
},
{
"path": "minemeld/traced/main.py",
"chars": 3669,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/traced/purge.py",
"chars": 4885,
"preview": "#!/usr/bin/env python\n\nimport logging\nimport os\nimport time\nimport sys\nimport argparse\nimport shutil\nimport json\nimport "
},
{
"path": "minemeld/traced/queryprocessor.py",
"chars": 7366,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/traced/storage.py",
"chars": 10778,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "minemeld/traced/writer.py",
"chars": 2567,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "nodes.json",
"chars": 4630,
"preview": "{\n \"minemeld.ft.anomali.Intelligence\": {\n \"class\": \"minemeld.ft.anomali:Intelligence\"\n },\n \"minemeld.ft."
},
{
"path": "requirements-dev.txt",
"chars": 153,
"preview": "Sphinx==1.3.1\nsphinx-rtd-theme==0.1.8\ntox==2.1.1\nmock==1.3.0\ngit+https://github.com/PaloAltoNetworks/platter#egg=platter"
},
{
"path": "requirements-web.txt",
"chars": 126,
"preview": "Flask==0.12.4\ngunicorn==19.5.0\npsutil==5.6.6\nFlask-Login==0.2.11\npasslib==1.6.5\nrrdtool==0.1.2\nsupervisor==3.1.3\nblinker"
},
{
"path": "requirements.txt",
"chars": 474,
"preview": "pip>=9.0.1\namqp==1.4.6\ngevent==1.0.2\ngreenlet==0.4.7\nhiredis==0.2.0\nPyYAML==5.4\nredis==2.10.5\nrequests==2.20.0\nplyvel==0"
},
{
"path": "scripts/prebuild-script.sh",
"chars": 39,
"preview": "#!/bin/bash\n\npip install cython==0.24\n\n"
},
{
"path": "setup.py",
"chars": 3480,
"preview": "# Copyright 2015-2017 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# y"
},
{
"path": "tests/comm_mock.py",
"chars": 1502,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/empty.yml",
"chars": 0,
"preview": ""
},
{
"path": "tests/feeds.htpasswd",
"chars": 88,
"preview": "user1:$apr1$SdhtTFdb$br1vVDVDr3r/ZYTo0aj.L0\nguest:$apr1$fUbzwJlK$tXcBNLcN8zhXNGjgB7M6./\n"
},
{
"path": "tests/integration/basic/DomainHC%3Fv%3Dcarbonblack.result",
"chars": 119642,
"preview": "{\n\"feedinfo\": {\n \"category\": \"MineMeld\", \"icon\": \"iVBORw0KGgoAAAANSUhEUgAAASwAAAFLCAYAAABsjLGXAAAMFmlDQ1BJQ0MgUHJvZmls"
},
{
"path": "tests/integration/basic/IPv4.lst",
"chars": 4715,
"preview": "103.249.88.244-103.249.88.244\n103.89.88.88-103.89.88.88\n104.18.34.162-104.18.34.162\n108.170.60.189-108.170.60.189\n109.23"
},
{
"path": "tests/integration/basic/IPv4HC%3Fs%3D5%26n%3D10.result",
"chars": 292,
"preview": "104.18.34.162-104.18.34.162\n108.170.60.189-108.170.60.189\n109.230.199.159-109.230.199.159\n109.230.199.169-109.230.199.16"
},
{
"path": "tests/integration/basic/IPv4HC%3Fv%3Dcsv%26f%3Dconfidence%26f%3Dsources%7Cfeeds%26f%3Dindicator%7Cclientip%26tr%3D1.result",
"chars": 4723,
"preview": "confidence,feeds,clientip\r\n100,localdb,1.1.1.0/27\r\n100,localdb,1.1.1.32/31\r\n100,localdb,1.1.2.0/24\r\n100,localdb,1.1.3.10"
},
{
"path": "tests/integration/basic/IPv4HC%3Fv%3Djson%26tr%3D1.result",
"chars": 29058,
"preview": "[\n{\"indicator\":\"1.1.1.0/27\",\"value\":{\"sources\":[\"localdb\"],\"confidence\":100,\"first_seen\":1550570114477,\"type\":\"IPv4\",\"sh"
},
{
"path": "tests/integration/basic/IPv4HC%3Fv%3Djson-seq.result",
"chars": 30419,
"preview": "\u001e{\"indicator\":\"1.1.1.0-1.1.1.33\",\"value\":{\"sources\":[\"localdb\"],\"confidence\":100,\"first_seen\":1550570114477,\"type\":\"IPv4"
},
{
"path": "tests/integration/basic/IPv4HC%3Fv%3Dmwg.result",
"chars": 6743,
"preview": "type=string\n\"1.1.1.0-1.1.1.33\" \"localdb\"\n\"1.1.2.0-1.1.2.255\" \"localdb\"\n\"1.1.3.10-1.1.3.44\" \"localdb\"\n\"103.249.88.244-103"
},
{
"path": "tests/integration/basic/IPv4HC.result",
"chars": 4715,
"preview": "1.1.1.0-1.1.1.33\n1.1.2.0-1.1.2.255\n1.1.3.10-1.1.3.44\n103.249.88.244-103.249.88.244\n103.89.88.88-103.89.88.88\n104.18.34.1"
},
{
"path": "tests/integration/basic/README.md",
"chars": 247,
"preview": "# Simple script to exercise and test feed output formats.\n\n## Usage\n\n```\nexport MM_URL=https://192.168.55.169\nexport MM_"
},
{
"path": "tests/integration/basic/URL.lst",
"chars": 8353,
"preview": "http://7-eleven-handbags.com/X1rZYp.php\nhttp://8vs.com/6jezbr.php\nhttp://abdal.com.ua/7_jzay.php\nhttp://aditaborai.com.b"
},
{
"path": "tests/integration/basic/URLHC%3Fs%3D5%26n%3D10.result",
"chars": 477,
"preview": "http://aditaborai.com.br/WgNGXe.php\nhttp://airconditioning12601.com/uploads/3/5/7/6/3576233/V5k3Za.php\nhttp://allreadytr"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dbluecoat%26cd%3Dtest.result",
"chars": 6876,
"preview": "define category test\n*.example.com/foobar?a=:80\n*.feyda.net/hoedr4.php\n7-eleven-handbags.com/x1rzyp.php\n8vs.com/6jezbr.p"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dbluecoat.result",
"chars": 0,
"preview": ""
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dcsv%26f%3Dconfidence%26f%3Dsources%7Cfeeds%26f%3Dindicator%7Curl.result",
"chars": 11157,
"preview": "confidence,feeds,url\r\n100,localdb,*abc.example.com/foobar?a=:80\r\n100,localdb,http://*.feyda.net/hOeDr4.php\r\n100,localdb,"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Djson%26tr%3D1.result",
"chars": 40883,
"preview": "[\n{\"indicator\":\"*abc.example.com/foobar?a=:80\",\"value\":{\"sources\":[\"localdb\"],\"confidence\":100,\"first_seen\":156102998530"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Djson-seq.result",
"chars": 40881,
"preview": "\u001e{\"indicator\":\"*abc.example.com/foobar?a=:80\",\"value\":{\"sources\":[\"localdb\"],\"confidence\":100,\"first_seen\":1561029985300"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dmwg.result",
"chars": 10933,
"preview": "type=string\n\"*abc.example.com/foobar?a=:80\" \"localdb\"\n\"http://*.feyda.net/hOeDr4.php\" \"localdb\"\n\"http://7-eleven-handbag"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dpanosurl%26di%3D1.result",
"chars": 6816,
"preview": "feyda.net/hoedr4.php\n*.feyda.net/hoedr4.php\n7-eleven-handbags.com/x1rzyp.php\n8vs.com/6jezbr.php\nabdal.com.ua/7_jzay.php\n"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dpanosurl%26sp%3D1%26nsl%3D1.result",
"chars": 6884,
"preview": "example.com/foobar?a=:80\n*.example.com/foobar?a=:80\nfeyda.net/hoedr4.php\n*.feyda.net/hoedr4.php\n7-eleven-handbags.com/x1"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dpanosurl%26sp%3D1.result",
"chars": 6885,
"preview": "example.com/foobar?a=:80\n*.example.com/foobar?a=:80\nfeyda.net/hoedr4.php\n*.feyda.net/hoedr4.php\n7-eleven-handbags.com/x1"
},
{
"path": "tests/integration/basic/URLHC%3Fv%3Dpanosurl.result",
"chars": 6868,
"preview": "example.com/foobar?a=:80\n*.example.com/foobar?a=:80\nfeyda.net/hoedr4.php\n*.feyda.net/hoedr4.php\n7-eleven-handbags.com/x1"
},
{
"path": "tests/integration/basic/URLHC.result",
"chars": 8353,
"preview": "*abc.example.com/foobar?a=:80\nhttp://*.feyda.net/hOeDr4.php\nhttp://7-eleven-handbags.com/X1rZYp.php\nhttp://8vs.com/6jezb"
},
{
"path": "tests/integration/basic/domain.lst",
"chars": 51187,
"preview": "25z5g623wpqpdwis.onion.to\n27c73bq66y4xqoh7.dorfact.at\n27lelchgcvs2wpm7.3lhjyx.top\n27lelchgcvs2wpm7.7jiff7.top\n27lelchgcv"
},
{
"path": "tests/integration/basic/gen-results.sh",
"chars": 1788,
"preview": "#!/bin/bash\n\ncurl -# -k -o IPv4HC.result \"https://127.0.0.1/feeds/IPv4HC\" -o IPv4HC.result\ncurl -# -k -o IPv4HC%3Fs%3D5%"
},
{
"path": "tests/integration/basic/test.py",
"chars": 9695,
"preview": "#!/usr/bin/env python2\n\nimport logging\nimport time\nimport urllib\nimport os\nimport sys\nimport re\n\nfrom itertools import i"
},
{
"path": "tests/panos_mock.py",
"chars": 2680,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/st_profile.py",
"chars": 2050,
"preview": "#!/usr/bin/env python\n\n# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "tests/test-prototype-1.yml",
"chars": 61,
"preview": "nodes:\n testprototype:\n prototype: testproto.test\n\n"
},
{
"path": "tests/test_comm_amqp.py",
"chars": 2419,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_device_list.yml",
"chars": 111,
"preview": "- name: test\n hostname: 192.168.55.152\n api_username: admin\n api_password: admin\n- name: test2\n tag: ngfw1\n"
},
{
"path": "tests/test_device_list2.yml",
"chars": 111,
"preview": "- name: test2\n tag: ngfw2\n- name: test\n hostname: 192.168.55.152\n api_username: admin\n api_password: admin\n"
},
{
"path": "tests/test_flask_aaa.py",
"chars": 53106,
"preview": "# Copyright 2016 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_autofocus.py",
"chars": 3129,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_base.py",
"chars": 8270,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_basepoller.py",
"chars": 42301,
"preview": "# -*- coding: utf-8 -*-\n# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (t"
},
{
"path": "tests/test_ft_boolexpr.py",
"chars": 4076,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_dag.py",
"chars": 19700,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_dag_devicepusher_op__show__object__registered_ip__ip_192_168_1_1__ip___registered_ip___object___show__0.xml",
"chars": 353,
"preview": "<response status=\"success\">\n <result>\n <entry from_agent=\"0\" ip=\"192.168.1.1\" persistent=\"1\">\n <tag"
},
{
"path": "tests/test_ft_dag_devicepusher_op__show__object__registered_ip__ip_192_168_1_2__ip___registered_ip___object___show__0.xml",
"chars": 307,
"preview": "<response status=\"success\">\n <result>\n <entry from_agent=\"0\" ip=\"192.168.1.2\" persistent=\"1\">\n <tag"
},
{
"path": "tests/test_ft_dag_devicepusher_op__show__object__registered_ip__tag__entry_name__mmeld_test_____tag___registered_ip___object___show__0.xml",
"chars": 414,
"preview": "<response status=\"success\">\n <result>\n <entry from_agent=\"0\" ip=\"192.168.1.1\" persistent=\"1\">\n <tag"
},
{
"path": "tests/test_ft_ipop.py",
"chars": 37840,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_local.py",
"chars": 5414,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_logstash.py",
"chars": 1815,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_op.py",
"chars": 22774,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
},
{
"path": "tests/test_ft_redis.py",
"chars": 8416,
"preview": "# Copyright 2015 Palo Alto Networks, Inc\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you ma"
}
]
// ... and 21 more files (download for full content)
About this extraction
This page contains the full source code of the PaloAltoNetworks/minemeld-core GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 221 files (1.7 MB), approximately 546.8k tokens, and a symbol index with 1840 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.