51124ed8c5
Modify the InstanceGroup (and, by extension, Heat and AWS AutoscalingGroup) types to give members in a FAILED state the highest priority for being removed when scaling down or being updated in a rolling update. Currently, FAILED resources are omitted when building a new template for the scaling group, so any such resources would never be replaced by one of the same name. This change will allow for continuity of naming in the case of a change that doesn't permanently remove the resource due to scaling down. Change-Id: I8fe93869dfbe4c4de6c48a65aeef0f71355eaf46 Partially-implements: blueprint mark-unhealthy
115 lines
3.7 KiB
Python
115 lines
3.7 KiB
Python
#
|
|
# 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 six
|
|
|
|
from heat.common import exception
|
|
|
|
|
|
def get_size(group, include_failed=False):
|
|
"""Get number of member resources managed by the specified group.
|
|
|
|
The size exclude failed members default, set include_failed=True
|
|
to get total size.
|
|
"""
|
|
if group.nested():
|
|
resources = [r for r in six.itervalues(group.nested())
|
|
if include_failed or r.status != r.FAILED]
|
|
return len(resources)
|
|
else:
|
|
return 0
|
|
|
|
|
|
def get_members(group, include_failed=False):
|
|
"""Get a list of member resources managed by the specified group.
|
|
|
|
Sort the list of instances first by created_time then by name.
|
|
If include_failed is set, failed members will be put first in the
|
|
list sorted by created_time then by name.
|
|
"""
|
|
resources = []
|
|
if group.nested():
|
|
resources = [r for r in six.itervalues(group.nested())
|
|
if include_failed or r.status != r.FAILED]
|
|
|
|
return sorted(resources,
|
|
key=lambda r: (r.status != r.FAILED, r.created_time, r.name))
|
|
|
|
|
|
def get_member_refids(group, exclude=None):
|
|
"""Get a list of member resources managed by the specified group.
|
|
|
|
The list of resources is sorted first by created_time then by name.
|
|
"""
|
|
members = get_members(group)
|
|
if len(members) == 0:
|
|
return []
|
|
|
|
if exclude is None:
|
|
exclude = []
|
|
return [r.FnGetRefId() for r in members
|
|
if r.FnGetRefId() not in exclude]
|
|
|
|
|
|
def get_member_names(group):
|
|
"""Get a list of resource names of the resources in the specified group.
|
|
|
|
Failed resources will be ignored.
|
|
"""
|
|
return [r.name for r in get_members(group)]
|
|
|
|
|
|
def get_resource(stack, resource_name, use_indices, key):
|
|
nested_stack = stack.nested()
|
|
if not nested_stack:
|
|
return None
|
|
try:
|
|
if use_indices:
|
|
return get_members(stack)[int(resource_name)]
|
|
else:
|
|
return nested_stack[resource_name]
|
|
except (IndexError, KeyError):
|
|
raise exception.InvalidTemplateAttribute(resource=stack.name,
|
|
key=key)
|
|
|
|
|
|
def get_rsrc_attr(stack, key, use_indices, resource_name, *attr_path):
|
|
resource = get_resource(stack, resource_name, use_indices, key)
|
|
if resource:
|
|
return resource.FnGetAtt(*attr_path)
|
|
|
|
|
|
def get_rsrc_id(stack, key, use_indices, resource_name):
|
|
resource = get_resource(stack, resource_name, use_indices, key)
|
|
if resource:
|
|
return resource.FnGetRefId()
|
|
|
|
|
|
def get_nested_attrs(stack, key, use_indices, *path):
|
|
path = key.split(".", 2)[1:] + list(path)
|
|
if len(path) > 1:
|
|
return get_rsrc_attr(stack, key, use_indices, *path)
|
|
else:
|
|
return get_rsrc_id(stack, key, use_indices, *path)
|
|
|
|
|
|
def get_member_definitions(group, include_failed=False):
|
|
"""Get member definitions in (name, ResourceDefinition) pair for group.
|
|
|
|
The List is sorted first by created_time then by name.
|
|
If include_failed is set, failed members will be put first in the
|
|
List sorted by created_time then by name.
|
|
"""
|
|
return [(resource.name, resource.t)
|
|
for resource in get_members(group, include_failed)]
|