backend/bms_app/wave/views.py (110 lines of code) (raw):

# Copyright 2022 Google LLC # # 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. from flask import request from marshmallow import ValidationError from bms_app.models import ( BMSServer, Mapping, Operation, OperationDetails, SourceDB, SourceDBType, Wave, db ) from bms_app.schema import AddWaveSchema, WaveSchema from bms_app.services.utils import generate_target_gcp_logs_link from bms_app.wave import bp from bms_app.wave.services import ( GetWaveService, list_waves_service, validate_wave_name_is_unique ) from bms_app.wave.services.waves import assign_source_db_wave @bp.route('', methods=['GET']) def list_waves(): """Return all available waves.""" project_id = request.args.get('project_id', type=int) data = list_waves_service(project_id) return { 'data': data } @bp.route('/<int:wave_id>', methods=['GET']) def get_wave(wave_id): """Return wave.""" return GetWaveService.run( wave_id=wave_id, return_details=request.args.get('details') ) @bp.route('/<int:wave_id>/operations/<int:operation_id>/details', methods=['GET']) def get_operation_details(wave_id, operation_id): """Return details/histories of the particular operation.""" query = db.session.query(OperationDetails, SourceDB, BMSServer) \ .join(Mapping, OperationDetails.mapping_id == Mapping.id) \ .join(SourceDB, Mapping.db_id == SourceDB.id) \ .join(BMSServer, Mapping.bms_id == BMSServer.id) \ .filter(OperationDetails.operation_id == operation_id) \ .all() response = {} for op_details, source_db, bms_server in query: db_id = source_db.id if db_id not in response: response[db_id] = { 'status': op_details.status.value, 'operation_id': op_details.operation_id, 'operation_type': op_details.operation_type.value, 'wave_id': op_details.wave_id, 'source_db': { 'source_hostname': source_db.server, 'db_name': source_db.db_name, 'db_type': source_db.db_type.value, 'is_rac': source_db.db_type == SourceDBType.RAC, 'oracle_version': source_db.oracle_version, }, 'bms': [] } logs_url = generate_target_gcp_logs_link(op_details, bms_server) response[db_id]['bms'].append({ 'id': bms_server.id, 'name': bms_server.name, 'logs_url': logs_url, 'started_at': op_details.started_at.strftime("%a, %d %b %Y %H:%M:%S GMT"), 'completed_at': op_details.completed_at.strftime("%a, %d %b %Y %H:%M:%S GMT"), 'step': op_details.step, 'mapping_id': op_details.mapping_id }) return {'data': list(response.values())} @bp.route('/<int:wave_id>', methods=['DELETE']) def delete_wave(wave_id): """Delete wave.""" operation_exists = db.session.query(Wave, Operation) \ .filter(Operation.wave_id == Wave.id) \ .filter(Wave.id == wave_id).count() if operation_exists: raise ValidationError({'wave_id': ['wave is not empty']}) SourceDB.query.filter(SourceDB.wave_id == wave_id).update({'wave_id': None}) wave = Wave.query.get_or_404(wave_id) db.session.delete(wave) db.session.commit() return {}, 204 @bp.route('/<int:wave_id>', methods=['PUT']) def edit_wave(wave_id): """Update wave.""" validated_data = WaveSchema(only=['name', 'project_id']).load(request.json) wave = Wave.query.get_or_404(wave_id) validate_wave_name_is_unique( validated_data['name'], wave.project_id, exclude_wave_id=wave_id ) wave.name = validated_data['name'] db.session.add(wave) db.session.commit() return WaveSchema().dump(wave) @bp.route('', methods=['POST']) def add_wave(): """Add wave.""" validated_data = AddWaveSchema().load(request.json) wave = db.session.query(Wave).filter( Wave.name == validated_data['name'], Wave.project_id == validated_data['project_id'] ).first() if not wave: wave = Wave( name=validated_data['name'], project_id=validated_data['project_id'] ) db.session.add(wave) db.session.commit() response = {} if validated_data.get('db_ids'): assigment_result = assign_source_db_wave( wave=wave, db_ids=validated_data['db_ids'] ) response.update(assigment_result) return response, 201