188 lines
6.3 KiB
Python
188 lines
6.3 KiB
Python
# Copyright 2014 Huawei Technologies Co. Ltd
|
|
#
|
|
# 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.
|
|
|
|
"""Cluster health check report."""
|
|
import logging
|
|
|
|
from compass.db.api import cluster as cluster_api
|
|
from compass.db.api import database
|
|
from compass.db.api import host as host_api
|
|
from compass.db.api import permission
|
|
from compass.db.api import user as user_api
|
|
from compass.db.api import utils
|
|
from compass.db import exception
|
|
from compass.db import models
|
|
|
|
|
|
REQUIRED_INSERT_FIELDS = ['name']
|
|
OPTIONAL_INSERT_FIELDS = [
|
|
'display_name', 'report', 'category', 'state', 'error_message'
|
|
]
|
|
UPDATE_FIELDS = ['report', 'state', 'error_message']
|
|
RESP_FIELDS = [
|
|
'cluster_id', 'name', 'display_name', 'report',
|
|
'category', 'state', 'error_message'
|
|
]
|
|
RESP_ACTION_FIELDS = ['cluster_id', 'status']
|
|
|
|
|
|
@utils.supported_filters(REQUIRED_INSERT_FIELDS, OPTIONAL_INSERT_FIELDS)
|
|
@database.run_in_session()
|
|
@utils.wrap_to_dict(RESP_FIELDS)
|
|
def add_report_record(cluster_id, name=None, report={},
|
|
state='verifying', session=None, **kwargs):
|
|
"""Create a health check report record."""
|
|
# Replace any white space into '-'
|
|
words = name.split()
|
|
name = '-'.join(words)
|
|
cluster = cluster_api.get_cluster_internal(cluster_id, session=session)
|
|
return utils.add_db_object(
|
|
session, models.HealthCheckReport, True, cluster.id, name,
|
|
report=report, state=state, **kwargs
|
|
)
|
|
|
|
|
|
def _get_report(cluster_id, name, session=None):
|
|
cluster = cluster_api.get_cluster_internal(cluster_id, session=session)
|
|
return utils.get_db_object(
|
|
session, models.HealthCheckReport, cluster_id=cluster.id, name=name
|
|
)
|
|
|
|
|
|
@utils.supported_filters(UPDATE_FIELDS)
|
|
@database.run_in_session()
|
|
@utils.wrap_to_dict(RESP_FIELDS)
|
|
def update_report(cluster_id, name, session=None, **kwargs):
|
|
"""Update health check report."""
|
|
report = _get_report(cluster_id, name, session=session)
|
|
if report.state == 'finished':
|
|
err_msg = 'Report cannot be updated if state is in "finished"'
|
|
raise exception.Forbidden(err_msg)
|
|
|
|
return utils.update_db_object(session, report, **kwargs)
|
|
|
|
|
|
@utils.supported_filters(UPDATE_FIELDS)
|
|
@database.run_in_session()
|
|
@utils.wrap_to_dict(RESP_FIELDS)
|
|
def update_multi_reports(cluster_id, session=None, **kwargs):
|
|
"""Bulk update reports."""
|
|
# TODO(grace): rename the fuction if needed to reflect the fact.
|
|
return set_error(cluster_id, session=session, **kwargs)
|
|
|
|
|
|
def set_error(cluster_id, report={}, session=None,
|
|
state='error', error_message=None):
|
|
cluster = cluster_api.get_cluster_internal(cluster_id, session=session)
|
|
logging.debug(
|
|
"updates all reports as %s in cluster %s",
|
|
state, cluster_id
|
|
)
|
|
return utils.update_db_objects(
|
|
session, models.HealthCheckReport,
|
|
updates={
|
|
'report': {},
|
|
'state': 'error',
|
|
'error_message': error_message
|
|
}, cluster_id=cluster.id
|
|
)
|
|
|
|
|
|
@database.run_in_session()
|
|
@user_api.check_user_permission(
|
|
permission.PERMISSION_LIST_HEALTH_REPORT
|
|
)
|
|
@utils.wrap_to_dict(RESP_FIELDS)
|
|
def list_health_reports(cluster_id, user=None, session=None):
|
|
"""List all reports in the specified cluster."""
|
|
cluster = cluster_api.get_cluster_internal(cluster_id, session=session)
|
|
return utils.list_db_objects(
|
|
session, models.HealthCheckReport, cluster_id=cluster.id
|
|
)
|
|
|
|
|
|
@database.run_in_session()
|
|
@user_api.check_user_permission(
|
|
permission.PERMISSION_GET_HEALTH_REPORT
|
|
)
|
|
@utils.wrap_to_dict(RESP_FIELDS)
|
|
def get_health_report(cluster_id, name, user=None, session=None):
|
|
return _get_report(
|
|
cluster_id, name, session=session
|
|
)
|
|
|
|
|
|
@database.run_in_session()
|
|
@user_api.check_user_permission(
|
|
permission.PERMISSION_DELETE_REPORT
|
|
)
|
|
@utils.wrap_to_dict(RESP_FIELDS)
|
|
def delete_reports(cluster_id, name=None, user=None, session=None):
|
|
# TODO(grace): better to separate this function into two.
|
|
# One is to delete a report of a cluster, the other to delete all
|
|
# reports under a cluster.
|
|
if name:
|
|
report = _get_report(cluster_id, name, session=session)
|
|
return utils.del_db_object(session, report)
|
|
else:
|
|
cluster = cluster_api.get_cluster_internal(
|
|
cluster_id, session=session
|
|
)
|
|
return utils.del_db_objects(
|
|
session, models.HealthCheckReport, cluster_id=cluster.id
|
|
)
|
|
|
|
|
|
@utils.supported_filters(optional_support_keys=['check_health'])
|
|
@database.run_in_session()
|
|
@user_api.check_user_permission(
|
|
permission.PERMISSION_CHECK_CLUSTER_HEALTH
|
|
)
|
|
@utils.wrap_to_dict(RESP_ACTION_FIELDS)
|
|
def start_check_cluster_health(cluster_id, send_report_url,
|
|
user=None, session=None, check_health={}):
|
|
"""Start to check cluster health."""
|
|
cluster = cluster_api.get_cluster_internal(cluster_id, session=session)
|
|
|
|
if cluster.state.state != 'SUCCESSFUL':
|
|
logging.debug("state is %s" % cluster.state.state)
|
|
err_msg = "Healthcheck starts only after cluster finished deployment!"
|
|
raise exception.Forbidden(err_msg)
|
|
|
|
reports = utils.list_db_objects(
|
|
session, models.HealthCheckReport,
|
|
cluster_id=cluster.id, state='verifying'
|
|
)
|
|
if reports:
|
|
err_msg = 'Healthcheck in progress, please wait for it to complete!'
|
|
raise exception.Forbidden(err_msg)
|
|
|
|
# Clear all preivous report
|
|
# TODO(grace): the delete should be moved into celery task.
|
|
# We should consider the case that celery task is down.
|
|
utils.del_db_objects(
|
|
session, models.HealthCheckReport, cluster_id=cluster.id
|
|
)
|
|
|
|
from compass.tasks import client as celery_client
|
|
celery_client.celery.send_task(
|
|
'compass.tasks.cluster_health',
|
|
(cluster.id, send_report_url, user.email)
|
|
)
|
|
return {
|
|
"cluster_id": cluster.id,
|
|
"status": "start to check cluster health."
|
|
}
|