Skip to content

Instantly share code, notes, and snippets.

@yeukhon
Last active January 2, 2016 13:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yeukhon/8309083 to your computer and use it in GitHub Desktop.
Save yeukhon/8309083 to your computer and use it in GitHub Desktop.
Usage: chmod +x generate-plugin.py ./generate-plugin config.ini
[plugin]
; output directory (if input /home/user, output to /home/user/{plugin_package_name})
location: ?
; plugin name: ZAP, Django Security, O-SAFT
plugin_name: ?
; plugin package name: minion-zap-plugin, minion-django-security-plugin, minion-osaft-plugin
plugin_package_name: minion-?-plugin
; plugin class name: ZAPPlugin, DjangoSecurityPlugin, OSAFTPlugin
plugin_class_name: ?Plugin
; plugin file name: zap_plugin.py, django_security_plugin.py, osaft_plugin.py
plugin_filename: ?.py
; whether the plugin will invoke an external tool or not y/n
require_external_process: n
#!/usr/bin/python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import copy
import ConfigParser
import os
import sys
setup = """\
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from setuptools import setup
install_requires = []
setup(name="{plugin_package_name}",
version="0.0",
description="{plugin_name} Plugin for Minion",
url="",
author="",
author_email="",
packages=['minion', 'minion.plugins', 'minion.plugins.{plugin_filename}'],
namespace_packages=['minion', 'minion.plugins'],
include_package_data=True,
install_requires=install_requires)
"""
init = """\
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
__import__('pkg_resources').declare_namespace(__name__)
"""
import_init = """\
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from {plugin_filename} import {plugin_class_name}
"""
plugin_class_file_1 = """\
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from minion.plugins.base import ExternalProcessPlugin
class {plugin_class_name}(ExternalProcessPlugin):
PLUGIN_NAME = "{plugin_name}"
PLUGIN_VERSION = "0.0"
"""
plugin_class_file_2 = """\
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from minion.plugins.base import BlockingPlugin
class {plugin_class_name}(BlockingPlugin):
PLUGIN_NAME = "{plugin_name}"
PLUGIN_VERSION = "0.0"
"""
def make_dir(path):
if os.path.exists(path):
raise SystemExit("{path} already exist. We don't override existing directory.".format(path=path))
else:
os.makedirs(path)
def make_file(path, template, format_strings):
text = copy.deepcopy(template)
format_text = text.format(**format_strings)
if os.path.exists(path):
raise SystemExit("{path} already exist. We don't override exisiting file.".format(path=path))
else:
with open(path, 'w+') as f:
f.write(format_text)
def ask_and_do(config_path):
config = ConfigParser.ConfigParser()
config.read(config_path)
location = config.get("plugin", "location")
plugin_name = config.get("plugin", "plugin_name")
plugin_package_name = config.get("plugin", "plugin_package_name")
plugin_class_name = config.get("plugin", "plugin_class_name")
plugin_filename = config.get("plugin", "plugin_filename")
require_external = config.get("plugin", "require_external_process")
if require_external.lower() == "y":
require_external = True
else:
require_external = False
# create a folder called minion-XXXXXXX-plugin
plugin_dir_path = os.path.join(location, plugin_package_name)
make_dir(plugin_dir_path)
# create setup.py
setup_py_path = os.path.join(plugin_dir_path, "setup.py")
make_file(setup_py_path, setup, {"plugin_package_name": plugin_package_name, \
"plugin_name": plugin_name, \
"plugin_filename": plugin_filename.split(".py")[0]})
# create minion folder
minion_path = os.path.join(plugin_dir_path, "minion")
make_dir(minion_path)
# create minion/__init__.py
minion_init_path = os.path.join(minion_path, "__init__.py")
make_file(minion_init_path, init, {})
# create plugins folder
plugins_path = os.path.join(minion_path, "plugins")
make_dir(plugins_path)
# create plugins/__init__.py
plugins_init_path = os.path.join(plugins_path, "__init__.py")
make_file(plugins_init_path, init, {})
# create the plugin folder that holds the plugin code
actual_plugin_path = os.path.join(plugins_path, plugin_filename.split(".py")[0])
make_dir(actual_plugin_path)
# create importable __init__.py
init_path = os.path.join(actual_plugin_path, "__init__.py")
make_file(init_path, import_init, {"plugin_filename": plugin_filename.split(".py")[0], \
"plugin_class_name": plugin_class_name})
# create plugin file
plugin_file_path = os.path.join(actual_plugin_path, plugin_filename)
if require_external:
f = plugin_class_file_1
else:
f = plugin_class_file_2
make_file(plugin_file_path, f, {"plugin_class_name": plugin_class_name, \
"plugin_name": plugin_name})
def main(config_path):
ask_and_do(config_path)
if __name__ == "__main__":
if len(sys.argv) < 2:
raise SystemExit("Usage: ./generate-plugin <config_path>")
else:
config_path = sys.argv[1]
main(config_path)
[plugin]
; output directory (if input /home/user, output to /home/user/{plugin_package_name})
location: /home/user
; plugin name: ZAP, Django Security, O-SAFT
plugin_name: Django Security
; plugin package name: minion-zap-plugin, minion-django-security-plugin, minion-osaft-plugin
plugin_package_name: minion-django-security-plugin
; plugin class name: ZAPPlugin, DjangoSecurityPlugin, OSAFTPlugin
plugin_class_name: DjangoSecurityPlugin
; plugin file name: zap_plugin.py, django_security_plugin.py, osaft_plugin.py
plugin_filename: django_security.py
; whether the plugin will invoke an external tool or not y/n
require_external_process: y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment