fuel-stats/collector/collector/api/resources/installation_structure.py

136 lines
4.4 KiB
Python

# Copyright 2014 Mirantis, Inc.
#
# 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 datetime import datetime
from dateutil import parser
from flask import Blueprint
from flask import request
from flask_jsonschema import validate as validate_request
bp = Blueprint('installation_structure', __name__)
from collector.api.app import app
from collector.api.app import db
from collector.api.common.util import db_transaction
from collector.api.common.util import exec_time
from collector.api.common.util import handle_response
from collector.api.config import packages_as_index
from collector.api.db.model import InstallationStructure
@bp.route('/', methods=['POST'])
@validate_request('installation_structure', 'request')
@handle_response('installation_structure', 'response')
@db_transaction
@exec_time
def post():
app.logger.debug(
"Handling installation_structure post request: {}".format(request.json)
)
structure = request.json['installation_structure']
master_node_uid = structure['master_node_uid']
obj = db.session.query(InstallationStructure).filter(
InstallationStructure.master_node_uid == master_node_uid).first()
if obj is None:
app.logger.debug("Saving new structure")
obj = InstallationStructure(master_node_uid=master_node_uid)
obj.creation_date = datetime.utcnow()
status_code = 201
else:
app.logger.debug("Updating structure {}".format(obj.id))
obj.modification_date = datetime.utcnow()
status_code = 200
obj.is_filtered = _is_filtered(structure)
obj.structure = structure
db.session.add(obj)
return status_code, {'status': 'ok'}
def _is_filtered_by_build_info(build_info, filtering_rules):
"""Calculates is build_info should be filtered or not.
:param build_info: build_id or packages from the
installation info structure
:param filtering_rules: filtering rules for release
"""
# We don't have 'build_id' in structure since release 8.0
# and 'packages' before 8.0
if build_info is None:
return False
build_info = packages_as_index(build_info)
# build info not found
if build_info not in filtering_rules:
return True
build_rules = filtering_rules.get(build_info)
# No from_dt specified
if build_rules is None:
return False
# from_dt in the past
from_dt = parser.parse(build_rules)
cur_dt = datetime.utcnow()
if from_dt <= cur_dt:
return False
return True
def _is_filtered(structure):
"""Checks is structure should be filtered or not.
For filtering uses rules defined at app.config['FILTERING_RULES']
:param structure: dict with installation info structure data
:return: bool
"""
rules = app.config.get('FILTERING_RULES')
app.logger.debug("Filtering by rules: %s", rules)
# No rules specified
if not rules:
return False
# Extracting data from structure
fuel_release = structure.get('fuel_release', {})
release = fuel_release.get('release')
build_id = fuel_release.get('build_id')
packages = structure.get('fuel_packages')
# Release not in rules
if release not in rules:
app.logger.debug("Release: %s not in rules. Not filtered",
release)
return True
filtering_rules = rules.get(release)
# Filtering rules doesn't specified
if filtering_rules is None:
app.logger.debug("Filtering rules are empty. Not filtered")
return False
filtered_by_build_id = _is_filtered_by_build_info(
build_id, filtering_rules)
app.logger.debug("Filtering by build_id: %s, result: %s",
build_id, filtered_by_build_id)
filtered_by_packages = _is_filtered_by_build_info(
packages, filtering_rules)
app.logger.debug("Filtering by packages: %s, result: %s",
packages, filtered_by_packages)
return filtered_by_build_id or filtered_by_packages