You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
5.6 KiB
Python
153 lines
5.6 KiB
Python
# Copyright (c) 2018 European Organization for Nuclear Research.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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.
|
|
|
|
|
|
import functools
|
|
|
|
from heatclient import exc
|
|
from oslo_log import log as logging
|
|
import six
|
|
|
|
from magnum.common import exception
|
|
from magnum.common import profiler
|
|
import magnum.conf
|
|
from magnum.drivers.common import driver
|
|
from magnum.i18n import _
|
|
from magnum.objects import fields
|
|
|
|
CONF = magnum.conf.CONF
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
# TODO(ttsiouts): notifications about nodegroup operations will be
|
|
# added in later commit.
|
|
|
|
|
|
ALLOWED_NODEGROUP_STATES = (
|
|
fields.ClusterStatus.CREATE_COMPLETE,
|
|
fields.ClusterStatus.UPDATE_COMPLETE,
|
|
fields.ClusterStatus.UPDATE_IN_PROGRESS,
|
|
fields.ClusterStatus.UPDATE_FAILED,
|
|
fields.ClusterStatus.RESUME_COMPLETE,
|
|
fields.ClusterStatus.RESTORE_COMPLETE,
|
|
fields.ClusterStatus.ROLLBACK_COMPLETE,
|
|
fields.ClusterStatus.SNAPSHOT_COMPLETE,
|
|
fields.ClusterStatus.CHECK_COMPLETE,
|
|
fields.ClusterStatus.ADOPT_COMPLETE
|
|
)
|
|
|
|
|
|
def allowed_operation(func):
|
|
@functools.wraps(func)
|
|
def wrapper(self, context, cluster, nodegroup, *args, **kwargs):
|
|
# Before we begin we need to check the status
|
|
# of the cluster. If the cluster is in a status
|
|
# that does not allow nodegroup creation we just
|
|
# fail.
|
|
if ('status' in nodegroup
|
|
and nodegroup.status not in ALLOWED_NODEGROUP_STATES):
|
|
operation = _(
|
|
'%(fname)s when nodegroup status is "%(status)s"'
|
|
) % {'fname': func.__name__, 'status': cluster.status}
|
|
raise exception.NotSupported(operation=operation)
|
|
return func(self, context, cluster, nodegroup, *args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
@profiler.trace_cls("rpc")
|
|
class Handler(object):
|
|
|
|
@allowed_operation
|
|
def nodegroup_create(self, context, cluster, nodegroup):
|
|
LOG.debug("nodegroup_conductor nodegroup_create")
|
|
cluster.status = fields.ClusterStatus.UPDATE_IN_PROGRESS
|
|
cluster.save()
|
|
nodegroup.status = fields.ClusterStatus.CREATE_IN_PROGRESS
|
|
nodegroup.create()
|
|
|
|
try:
|
|
cluster_driver = driver.Driver.get_driver_for_cluster(context,
|
|
cluster)
|
|
cluster_driver.create_nodegroup(context, cluster, nodegroup)
|
|
nodegroup.save()
|
|
except Exception as e:
|
|
nodegroup.status = fields.ClusterStatus.CREATE_FAILED
|
|
nodegroup.status_reason = six.text_type(e)
|
|
nodegroup.save()
|
|
cluster.status = fields.ClusterStatus.UPDATE_FAILED
|
|
cluster.save()
|
|
if isinstance(e, exc.HTTPBadRequest):
|
|
e = exception.InvalidParameterValue(message=six.text_type(e))
|
|
raise e
|
|
raise
|
|
return nodegroup
|
|
|
|
@allowed_operation
|
|
def nodegroup_update(self, context, cluster, nodegroup):
|
|
LOG.debug("nodegroup_conductor nodegroup_update")
|
|
cluster.status = fields.ClusterStatus.UPDATE_IN_PROGRESS
|
|
cluster.save()
|
|
nodegroup.status = fields.ClusterStatus.UPDATE_IN_PROGRESS
|
|
|
|
try:
|
|
cluster_driver = driver.Driver.get_driver_for_cluster(context,
|
|
cluster)
|
|
cluster_driver.update_nodegroup(context, cluster, nodegroup)
|
|
nodegroup.save()
|
|
except Exception as e:
|
|
nodegroup.status = fields.ClusterStatus.UPDATE_FAILED
|
|
nodegroup.status_reason = six.text_type(e)
|
|
nodegroup.save()
|
|
cluster.status = fields.ClusterStatus.UPDATE_FAILED
|
|
cluster.save()
|
|
if isinstance(e, exc.HTTPBadRequest):
|
|
e = exception.InvalidParameterValue(message=six.text_type(e))
|
|
raise e
|
|
raise
|
|
|
|
return nodegroup
|
|
|
|
def nodegroup_delete(self, context, cluster, nodegroup):
|
|
LOG.debug("nodegroup_conductor nodegroup_delete")
|
|
cluster.status = fields.ClusterStatus.UPDATE_IN_PROGRESS
|
|
cluster.save()
|
|
nodegroup.status = fields.ClusterStatus.DELETE_IN_PROGRESS
|
|
|
|
try:
|
|
cluster_driver = driver.Driver.get_driver_for_cluster(context,
|
|
cluster)
|
|
cluster_driver.delete_nodegroup(context, cluster, nodegroup)
|
|
except exc.HTTPNotFound:
|
|
LOG.info('The nodegroup %s was not found during nodegroup'
|
|
' deletion.', nodegroup.uuid)
|
|
try:
|
|
nodegroup.destroy()
|
|
except exception.NodeGroupNotFound:
|
|
LOG.info('The nodegroup %s has been deleted by others.',
|
|
nodegroup.uuid)
|
|
return None
|
|
except exc.HTTPConflict:
|
|
raise exception.NgOperationInProgress(nodegroup=nodegroup.name)
|
|
except Exception as e:
|
|
nodegroup.status = fields.ClusterStatus.DELETE_FAILED
|
|
nodegroup.status_reason = six.text_type(e)
|
|
nodegroup.save()
|
|
cluster.status = fields.ClusterStatus.UPDATE_FAILED
|
|
cluster.save()
|
|
raise
|
|
return None
|