import github import glom import yaml import traceback from flask import Flask, abort, request, current_app, jsonify _flask = Flask(__name__) _flask.config.from_pyfile('config.py') @_flask.route('/healthz') def healthz(): return 'OK' @_flask.route("/api/apps/", methods=['PUT']) def apps(app_name): try: app_config = _flask.config['APPS'][app_name] except KeyError: abort(404) auth_token = request.headers.get('Authorization', '')[6:] if auth_token != app_config['api_token']: abort(401) new_image = request.get_json().get('image', '').strip() if not new_image: return jsonify(imgae="this field is required"), 400 if len(list(filter(lambda s: s, new_image.split(':')))) != 2: return jsonify(imgae="must be in format `:`"), 400 try: update_image(app_name, app_config, new_image) except Exception: current_app.logger.error(traceback.format_exc()) abort(500, traceback.format_exc()) return 'success' def update_image(app_name, app_config, new_image): g = github.Github(_flask.config['GITHUB_TOKEN']) repo = g.get_organization('pingcap-inc').get_repo('sre') file = repo.get_contents(app_config['file_name']) docs = list(yaml.load_all(file.decoded_content, yaml.Loader)) doc = docs[app_config['yaml_position']] image = glom.glom(doc, app_config['jq_path']) if image == new_image: current_app.logger.info('skipped') return edited_file = file.decoded_content.decode('utf8').replace(image, new_image) commit_message = f'🚀 [IMAGE UPDATER] update `{app_name}` to `{new_image}`' repo.update_file( app_config['file_name'], commit_message, edited_file, file.sha ) current_app.logger.info(commit_message) if __name__ == "__main__": _flask.run(host="0.0.0.0", port=5050)