fuel-web/nailgun/nailgun/api/v1/validators/node_group.py

141 lines
4.9 KiB
Python

# -*- coding: utf-8 -*-
# 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 distutils.version import StrictVersion
from nailgun.api.v1.validators.base import BasicValidator
from nailgun import consts
from nailgun.db import db
from nailgun import errors
from nailgun import objects
from nailgun.api.v1.validators.json_schema import node_group
class NodeGroupValidator(BasicValidator):
single_schema = node_group.single_schema
@classmethod
def _validate_unique_name(cls, data, *filters):
"""Validate node group name to be unique.
Validate whether node group name is unique for specific
environment. Prevent to have duplicated node group names for
the same environment.
:param data: data which contains node group name and cluster_id.
:param filters: additional filters for the query which is
used in the method for validation.
:type data: dict
:type filters: list
:returns: None
"""
nodegroup_query = objects.NodeGroupCollection.filter_by(
None, name=data['name'], cluster_id=data['cluster_id'])
if filters:
nodegroup_query = nodegroup_query.filter(*filters)
nodegroup_exists = db.query(nodegroup_query.exists()).scalar()
if nodegroup_exists:
raise errors.NotAllowed(
"Node group '{0}' already exists "
"in environment {1}.".format(
data['name'], data['cluster_id']))
@classmethod
def _validate_default_flag(self, data):
"""Vadidate default flag
Since changing of 'is_default' flag for node group is forbidden
this method validate such case
:param data: input request data
:type data: dict
"""
nodegroup = objects.NodeGroupCollection.filter_by(
None, name=data['name'], cluster_id=data['cluster_id']).first()
if nodegroup and data['is_default'] != nodegroup.is_default:
raise errors.NotAllowed(
"'default' flag for node group cannot be changed"
)
@classmethod
def _check_for_deployed_nodes(cls, cluster):
"""Check if nodes reconfiguration is allowed for cluster"""
env_version = cluster.release.environment_version
if not StrictVersion(env_version) >= StrictVersion('8.0'):
if any(objects.Cluster.get_nodes_by_status(
cluster,
consts.NODE_STATUSES.ready)):
raise errors.NotAllowed(
"Reconfiguration of nodes after the "
"deployment is allowed only for "
"environments 8.0 or greater."
)
@classmethod
def validate(cls, data):
data = cls.validate_json(data)
cluster = objects.Cluster.get_by_uid(
data['cluster_id'], fail_if_not_found=True)
cls._check_for_deployed_nodes(cluster)
cls._validate_unique_name(data)
if data.get('is_default'):
raise errors.NotAllowed(
"Default node group is created only by Nailgun."
)
if cluster.net_provider == consts.CLUSTER_NET_PROVIDERS.nova_network:
raise errors.NotAllowed(
"Node groups can only be created when using Neutron."
)
return data
@classmethod
def validate_delete(cls, data, instance):
if instance.is_default:
raise errors.CannotDelete(
"Default node group cannot be deleted."
)
if instance.nodes and not all(
node.status == consts.NODE_STATUSES.discover
for node in instance.nodes):
raise errors.CannotDelete(
"Node group can be deleted only when all its nodes "
"are in bootstrap state."
)
@classmethod
def validate_update(cls, data, instance):
data = cls.validate_json(data)
cls._validate_unique_name(
data, objects.NodeGroup.model.id != instance.id)
if 'is_default' in data:
cls._validate_default_flag(data)
if 'cluster_id' in data and data['cluster_id'] != instance.cluster_id:
raise errors.NotAllowed(
"Node group cannot be assigned to other cluster "
"after creation."
)
return data