From cf424da881aa2468356a1a5d6d585b49411aca27 Mon Sep 17 00:00:00 2001 From: ronny abraham Date: Thu, 13 Jul 2023 05:42:36 +0300 Subject: [PATCH] added a bootstrap.txt template file, and got rid of the old deploy_meta --- bin/deploy_meta.py | 497 --------------------------- bin/test.py | 90 ----- share/templates/meta/bootstrap.txt | 6 + share/templates/meta/development.yml | 7 +- 4 files changed, 11 insertions(+), 589 deletions(-) delete mode 100644 bin/deploy_meta.py delete mode 100644 bin/test.py create mode 100644 share/templates/meta/bootstrap.txt diff --git a/bin/deploy_meta.py b/bin/deploy_meta.py deleted file mode 100644 index e741f05..0000000 --- a/bin/deploy_meta.py +++ /dev/null @@ -1,497 +0,0 @@ -import os -import sys -import yaml -from PyQt5.QtWidgets import QMainWindow, QLineEdit, QLabel, QAction -from PyQt5.QtWidgets import QFileDialog, QGridLayout, QWidget, QApplication -from PyQt5.QtWidgets import QMessageBox -from PyQt5.QtCore import QVariant - - -class DictQuery(dict): - # https://www.haykranen.nl/2016/02/13/handling-complex - # -nested-dicts-in-python/ - def get(self, path, default=None): - keys = path.split(".") - val = None - - for key in keys: - if val: - if isinstance(val, list): - val = [v.get(key, default) if v else None for v in val] - else: - val = val.get(key, default) - else: - val = dict.get(self, key, default) - - if not val: - break - - return val - - -def create_path(path_str, delimiter="/"): - """ - helper function to crate a path from a string - - Keword Arguments: - path_str -- a "/" separated path - delimiter -- you can use a different delimiter - """ - - path = '' - - for d in path_str.split(delimiter): - path = os.path.join(path, d) - - return path - - -def nested_path(dic, path, value, delimiter='.'): - """ - sets the value in a dictionary object given a string key - separated by '.' - - Keyword Arguments: - path -- the string key whose path is separated by '.' - value -- the value we wish to set - delimiter -- the delimeter value used to separate the path - """ - - keys = path.split('.') - return nested_set(dic, keys, value) - - -def nested_set(dic, keys, value): - """ - sets the value in a dictionary object given a list object - of keys - - Keyword Arguments: - dic -- the dictionary object - keys -- the list object of keys - value -- the value we wish to set - """ - - for key in keys[:-1]: - dic = dic.setdefault(key, {}) - dic[keys[-1]] = value - - -class DeployMeta(QMainWindow): - - PATH_META = "../../../meta/project" - PATH_TEMPLATES = "../share/templates/meta" - - path_meta = None - path_templates = None - - default_store_file = "test.yml" - - currentbranch = None - config_data = None - - CONFIG_TYPES = { - 'development': 'development.yml', - 'staging': 'staging.yml', - 'production': 'staging.yml', - } - - widgets = None - - widgets_baseinfo = { - 'PROJECT_NAME': { - 'title': 'Project Name', - 'location': 'project.name', - }, - - 'PROJECT_IP': { - 'title': 'Project Host', - 'location': 'project.host', - }, - - 'BRANCH_NAME': { - 'title': 'Branch Name', - 'location': 'project.branch', - 'default': { - 'development': "development", - 'staging': "staging", - 'production': "production" - } - }, - - 'BRANCH_EXT': { - 'title': 'Branch Extension', - 'location': 'project.extension', - 'default': { - "development": "dev", - "staging": "stg", - "production": "prd" - } - }, - - 'BRANCH_USER': { - 'title': 'Branch User', - 'location': 'project.user', - 'default': { - "development": "ronny", - "staging": "website", - "production": "website" - } - }, - - 'BRANCH_GROUP': { - 'title': 'Branch Group', - 'location': 'project.group', - 'default': { - "development": "wheel", - "staging": "www-data", - "production": "www-data" - } - }, - - 'DATABASE_IP': { - 'title': 'Database IP', - 'location': 'database.host'}, - - 'DATABASE_PORT': { - 'title': 'Database Port', - 'location': 'database.port', - 'default': { - 'development': 'DOCKER_PORT', - "staging": "5432", - "production": "5432" - }, - }, - - 'DATABASE_NAME': { - 'title': 'Database Name', - 'location': 'database.name', - }, - - 'DATABASE_ADMIN_NAME': { - 'title': 'Database Admin Name', - 'location': 'database.users.admin.name', - 'default': { - "development": "admin", - "staging": "admin", - "production": "admin" - } - }, - - 'DATABASE_ADMIN_PASS': { - 'title': 'Database Admin Pass', - 'location': 'database.users.admin.pass', - 'default': { - 'development': "admin", - 'staging': "admin", - 'production': "admin" - } - }, - - 'DATABASE_USER_NAME': { - 'title': 'Database User Name', - 'location': 'database.users.default.name', - 'default': { - 'development': "ronny", - 'staging': "website", - 'production': "website" - } - }, - - 'DATABASE_USER_PASS': { - 'title': 'Database User Pass', - 'location': 'database.users.default.pass', - 'default': { - 'development': "admin", - 'staging': "admin", - 'production': "admin", - } - }, - - 'DJANGO_IP': { - 'title': 'Django IP Address', - 'location': 'django.host', - 'default': { - 'development': "127.0.0.1", - 'staging': None, - 'production': None - } - }, - - 'DJANGO_PORT': { - 'title': 'Django Port', - 'location': 'django.port', - 'default': { - 'development': None, - 'staging': "8000", - 'production': "8010", - }, - }, - - 'NGINX_PORT': { - 'title': 'Nginx Port', - 'location': 'nginx.port', - 'default': { - 'development': "8080", - 'staging': "80", - 'production': "80", - }, - } - } - - def __init__(self): - super(DeployMeta, self).__init__() - - # create the base path variables - self.path_meta = create_path(self.PATH_META) - self.path_templates = create_path(self.PATH_TEMPLATES) - - self.widgets = dict() - for key in self.widgets_baseinfo: - self.widgets[key] = dict() - self.widgets[key]['title'] = self.widgets_baseinfo[key]['title'] - self.widgets[key]['location'] = \ - self.widgets_baseinfo[key]['location'] - - if 'default' in self.widgets_baseinfo[key]: - self.widgets[key]['default'] = \ - self.widgets_baseinfo[key]['default'] - else: - self.widgets[key]['default'] = None - - self.widgets[key]['field'] = None - - self.initUI() - - def load_config(self, configname): - - if configname not in self.CONFIG_TYPES.keys(): - print("\nerror, load_config was called with parameter: {confname}," - "which is not a legitimate value in CONFIG TYPES." - "\nLegitimate values are {configvalues}".format( - confname=configname, - configvalues=self.CONFIG_TYPES.keys())) - sys.exit() - - path_config_full = os.path.join( - self.path_templates, self.CONFIG_TYPES[configname]) - - print("path_config_full: %s" % path_config_full) - - configuration_file = yaml.safe_load(open(path_config_full, 'r')) - return configuration_file - - def store_config(self): - - for key in self.widgets: - configvalue = str(self.widgets[key]['field'].text().__str__()) - - if configvalue.isdigit(): - configvalue = int(configvalue) - - nested_path( - self.config_data, - self.widgets[key]['location'], - configvalue) - - dquery = DictQuery(self.config_data) - - database_name = "{projectname}_{branchext}".format( - projectname=dquery.get('project.name'), - branchext=dquery.get('project.extension')) - - virtualenv_name = "{projectname}_{branchext}".format( - projectname=dquery.get('project.name'), - branchext=dquery.get('project.extension')) - - nested_path( - self.config_data, 'database.name', database_name) - - nested_path( - self.config_data, 'virtualenv.name', virtualenv_name) - - if self.currentbranch == 'development': - projectpath = "{projectname}.prj".format( - projectname=dquery.get('project.name')) - - nested_path( - self.config_data, 'project.paths.home', projectpath) - - nested_path( - self.config_data, 'virtualenv.name', - dquery.get('project.name')) - - def add_widgetrow(self, key, grid): - - row = grid.rowCount() - - title = self.widgets[key]['title'] - - label = QLabel(title) - field = QLineEdit() - - grid.addWidget(label, row, 0) - grid.addWidget(field, row, 1) - - self.widgets[key]['field'] = field - - def create_action(self, key): - title = key.capitalize() - menuname = "&%s" % title - shortcut = "Ctrl+%s" % title[0] - - desc = "Load Configuration %s" % title - - loadAction = QAction(menuname, self) - loadAction.setShortcut(shortcut) - loadAction.setStatusTip(desc) - loadAction.triggered.connect(self.action_loadconfig) - - variant = QVariant(key) - loadAction.setData(variant) - - return loadAction - - def action_loadconfig(self): - sender = self.sender() - - if type(sender.data()) is str: - self.currentbranch = sender.data() - else: - self.currentbranch = sender.data().toString().__str__() - - self.config_data = self.load_config(self.currentbranch) - - dquery = DictQuery(self.config_data) - for key in self.widgets: - configvalue = dquery.get(self.widgets[key]['location']) - - if self.widgets[key]['default']: - defaultvalue = self.widgets[key]['default'][self.currentbranch] - - if configvalue == key and defaultvalue is not None: - self.widgets[key]['field'].setText(defaultvalue) - else: - self.widgets[key]['field'].setText(str(configvalue)) - else: - self.widgets[key]['field'].setText(configvalue) - - def action_save_config(self): - - # first make sure we've loaded up a configuration - # file to save. currentbranch will be set if we - # loaded it up - - if self.currentbranch: - - self.store_config() - - # path_newconfig = os.path.join( - # self.path_meta, self.default_store_file) - - dialog_title = "Save {currentbranch} configuration".format( - currentbranch=self.currentbranch) - - # - # generate the default path to save to - - path_default_save = os.path.join( - self.path_meta, self.default_store_file) - - # - # get the path value from the dialog box - - path_newconfig = QFileDialog.getSaveFileName( - self, dialog_title, - path_default_save, - filter='*.yml') - - # - # if the user hit 'cancel' path_newconfig will be empty - - if path_newconfig: - stream = open(path_newconfig[0], 'w') - yaml.dump(self.config_data, stream) - - else: - # - # display message warning no configuration has been loaded - - msg = QMessageBox() - msg.setIcon(QMessageBox.Warning) - msg.setText('Save Error') - msg.setInformativeText( - "Cannot save modified configuration until you load one of the" - " default config types") - - retval = msg.exec_() - print("value of qmessagebox in action_save: %s" % retval) - - def setupMenu(self): - menubar = self.menuBar() - menubar.setNativeMenuBar(False) - - exitAction = QAction('&Exit', self) - exitAction.setShortcut('Ctrl+Q') - exitAction.setStatusTip("Exit application") - exitAction.triggered.connect(self.close) - - saveAction = QAction('&Gore', self) - saveAction.setShortcut('Ctrl+T') - saveAction.setStatusTip("Save Config File") - saveAction.triggered.connect(self.action_save_config) - - fileMenu = menubar.addMenu('&File') - fileMenu.addAction(exitAction) - fileMenu.addAction(saveAction) - - loadMenu = menubar.addMenu("&Load Configuration") - - for key in self.CONFIG_TYPES: - loadMenu.addAction(self.create_action(key)) - - def initUI(self): - - self.setupMenu() - - grid = QGridLayout() - grid.setSpacing(10) - - self.add_widgetrow('PROJECT_NAME', grid) - self.add_widgetrow('PROJECT_IP', grid) - self.add_widgetrow('BRANCH_NAME', grid) - self.add_widgetrow('BRANCH_EXT', grid) - self.add_widgetrow('BRANCH_USER', grid) - self.add_widgetrow('BRANCH_GROUP', grid) - self.add_widgetrow('DATABASE_IP', grid) - self.add_widgetrow('DATABASE_PORT', grid) - self.add_widgetrow('DATABASE_NAME', grid) - self.add_widgetrow('DATABASE_ADMIN_NAME', grid) - self.add_widgetrow('DATABASE_ADMIN_PASS', grid) - self.add_widgetrow('DATABASE_USER_NAME', grid) - self.add_widgetrow('DATABASE_USER_PASS', grid) - self.add_widgetrow('DJANGO_IP', grid) - self.add_widgetrow('DJANGO_PORT', grid) - self.add_widgetrow('NGINX_PORT', grid) - - central = QWidget() - central.setLayout(grid) - self.setCentralWidget(central) - - self.setGeometry(300, 300, 450, 300) - self.setWindowTitle("Deploy Meta Files") - self.show() - self.raise_() - - -def main(): - app = QApplication(sys.argv) - app.setStyle("cleanlooks") - ex = DeployMeta() - sys.exit(app.exec_()) - - print(ex) - - -if __name__ == '__main__': - main() diff --git a/bin/test.py b/bin/test.py deleted file mode 100644 index 74b0592..0000000 --- a/bin/test.py +++ /dev/null @@ -1,90 +0,0 @@ -import ruamel.yaml -import os -import argparse - -parser = argparse.ArgumentParser() -parser.add_argument('--file1', default='development.yml') -parser.add_argument('--file2', default='test.yml') - - -def findDiff(d1, d2, path=""): - for k in d1.keys(): - if not (k in d2): - print(path, ":") - print(k + " as key not in d2", "\n") - else: - if type(d1[k]) is dict: - if path == "": - path = k - else: - path = path + "->" + k - findDiff(d1[k], d2[k], path) - else: - if d1[k] != d2[k]: - print(path, ":") - print(" - ", k, " : ", d1[k]) - print(" + ", k, " : ", d2[k]) - - -def compare_dictionaries(dict_1, dict_2, dict_1_name, dict_2_name, path=""): - """Compare two dictionaries recursively to find non mathcing elements - - Args: - dict_1: dictionary 1 - dict_2: dictionary 2 - - Returns: - - """ - err = '' - key_err = '' - value_err = '' - old_path = path - for k in dict_1.keys(): - path = old_path + "[%s]" % k - if not (k in dict_2): - key_err += "Key %s%s not in %s\n" % ( - dict_2_name, path, dict_2_name) - else: - if isinstance(dict_1[k], dict) and isinstance(dict_2[k], dict): - err += compare_dictionaries( - dict_1[k], dict_2[k], 'd1', 'd2', path) - else: - if dict_1[k] != dict_2[k]: - value_err += "Value of %s%s (%s) not same as %s%s (%s)\n"\ - % (dict_1_name, - path, dict_1[k], dict_2_name, path, dict_2[k]) - - for k in dict_2.keys(): - path = old_path + "[%s]" % k - if not (k in dict_1): - key_err += "Key %s%s not in %s\n" % ( - dict_2_name, path, dict_1_name) - - return key_err + value_err + err - - -def create_path(path_str, delimiter="/"): - path = '' - - for d in path_str.split(delimiter): - path = os.path.join(path, d) - - return path - - -def main(): - path_meta = create_path("../../../meta/project") - - args = parser.parse_args() - - path_main = os.path.join(path_meta, args.file1) - path_test = os.path.join(path_meta, args.file2) - - yaml_main = ruamel.yaml.load(file(path_main, 'r')) - yaml_test = ruamel.yaml.load(file(path_test, 'r')) - - a = compare_dictionaries(yaml_main, yaml_test, 'main', 'test') - print(a) - -main() diff --git a/share/templates/meta/bootstrap.txt b/share/templates/meta/bootstrap.txt new file mode 100644 index 0000000..8aff9ff --- /dev/null +++ b/share/templates/meta/bootstrap.txt @@ -0,0 +1,6 @@ +Django +PyYAML +psycopg2 +pycryptodome +gunicorn +Jinja2 diff --git a/share/templates/meta/development.yml b/share/templates/meta/development.yml index 5216894..efe5726 100644 --- a/share/templates/meta/development.yml +++ b/share/templates/meta/development.yml @@ -24,9 +24,12 @@ logging: paths: [null] maintenance: nginx: - commands: {start: nginx, status: ps waux | grep nginx, stop: nginx -s stop} + commands: + start: brew services start nginx + status: brew services list | grep nginx + stop: brew services stop nginx editor: mvim - execute: sudo + execute: local supervisor: commands: {reload: supervisorctl reload, start: supervisorctl start, status: supervisorctl status, stop: supervisorctl stop, update: supervisorctl update}