diff --git a/muranorepository/api/utils.py b/muranorepository/api/utils.py index 196c4d3..b75325f 100644 --- a/muranorepository/api/utils.py +++ b/muranorepository/api/utils.py @@ -3,6 +3,7 @@ import shutil import re import tempfile import datetime +import yaml from flask import jsonify, abort from flask import make_response from werkzeug import secure_filename @@ -187,7 +188,7 @@ def perform_deletion(files_for_deletion, manifest_for_deletion): def save_archive(request): - err_resp = make_response('There is no data to upload', 409) + err_resp = make_response('There is no data to upload', 400) if request.content_type == 'application/octet-stream': data = request.environ['wsgi.input'].read() if not data: @@ -204,3 +205,22 @@ def save_archive(request): path_to_archive = os.path.join(CONF.cache_dir, filename) file_to_upload.save(path_to_archive) return path_to_archive + + +def create_service(data): + for parameter in ['full_service_name', 'service_display_name']: + if not data.get(parameter): + return make_response('There is no {parameter} in json'.format( + parameter=parameter), 400) + service_id = data.get('full_service_name') + path_to_manifest = os.path.join(CONF.manifests, + service_id + '-manifest.yaml') + try: + with open(path_to_manifest, 'w') as service_manifest: + service_manifest.write(yaml.dump(data, default_flow_style=False)) + except Exception as e: + log.exception(e) + if os.path.exists(path_to_manifest): + os.remove(path_to_manifest) + return make_response('Error during service manifest creation', 500) + return jsonify(result='success') diff --git a/muranorepository/api/v1.py b/muranorepository/api/v1.py index a25ceb2..aaba184 100644 --- a/muranorepository/api/v1.py +++ b/muranorepository/api/v1.py @@ -14,6 +14,7 @@ import os import tarfile import tempfile +import json from flask import Blueprint, send_file from flask import jsonify, request, abort from flask import make_response @@ -28,6 +29,21 @@ v1_api = Blueprint('v1', __name__) CONF = cfg.CONF +def convert(input): + """ + Convert unicode to regular strings + """ + if isinstance(input, dict): + return dict([(convert(key), convert(value)) + for key, value in input.iteritems()]) + elif isinstance(input, list): + return [convert(element) for element in input] + elif isinstance(input, unicode): + return input.encode('utf-8') + else: + return input + + @v1_api.route('/client/') def get_archive_data(client_type): if client_type not in CLIENTS_DICT.keys(): @@ -92,7 +108,8 @@ def upload_file_in_nested_path(data_type, path): api.check_data_type(data_type) if data_type == MANIFEST: - make_response('It is forbidden to upload manifests to subfolders', 403) + make_response('It is forbidden to upload manifests to subfolders', + 403) return api.save_file(request, data_type, path) @@ -213,3 +230,29 @@ def toggleEnabled(service_name): def reset_caches(): api.reset_cache() return jsonify(result='success') + + +@v1_api.route('/admin/services/create', methods=['PUT']) +def create_service(): + try: + service_data = convert(json.loads(request.data)) + except: + return make_response('Unable to load json data', 500) + resp = api.create_service(service_data) + api.reset_cache() + return resp + + +@v1_api.route('/admin/services/', methods=['POST']) +def update_service(service_name): + api.check_service_name(service_name) + parser = ManifestParser() + try: + service_data = convert(json.loads(request.data)) + except: + return make_response('Unable to load json data', 500) + result = parser.update_service(service_name, service_data) + if result: + api.reset_cache() + else: + return make_response('Unable to update service', 500) diff --git a/muranorepository/utils/parser.py b/muranorepository/utils/parser.py index 91c21e1..b997e5d 100644 --- a/muranorepository/utils/parser.py +++ b/muranorepository/utils/parser.py @@ -83,14 +83,18 @@ class ManifestParser(object): manifests.append(Manifest(manifest_data)) return manifests - def toggle_enabled(self, service_name): + def _get_manifest_path(self, service_name): + # ToDO: Rename manifests to it's id and remove this func manifests = self.parse() - path_to_manifest = None for manifest in manifests: if manifest.full_service_name == service_name: path_to_manifest = os.path.join(self.manifest_directory, manifest.manifest_file_name) - break + return path_to_manifest + return None + + def toggle_enabled(self, service_name): + path_to_manifest = self._get_manifest_path(service_name) if not path_to_manifest: log.error('There is no manifest ' 'file for {0} service'.format(service_name)) @@ -103,3 +107,19 @@ class ManifestParser(object): manifest_file.write(yaml.dump(service_manifest_data, default_flow_style=False)) return True + + def update_service(self, service_name, data): + path_to_manifest = self._get_manifest_path(service_name) + if not path_to_manifest: + log.error('There is no manifest ' + 'file for {0} service'.format(service_name)) + return False + with open(path_to_manifest) as stream: + service_manifest_data = yaml.load(stream) + for key, value in data.iteritems(): + service_manifest_data[key] = data[key] + + with open(path_to_manifest, 'w') as manifest_file: + manifest_file.write(yaml.dump(service_manifest_data, + default_flow_style=False)) + return True