ebcli/display/traditional.py (115 lines of code) (raw):
# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.s
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file 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 botocore.compat import six
from cement.utils.misc import minimal_logger
from ebcli.core import io
from ebcli.display import term
from ebcli.display.data_poller import DataPoller
from ebcli.display.screen import Screen
from ebcli.lib import ec2, elasticbeanstalk, elb, elbv2, utils
from ebcli.resources import statics
Queue = six.moves.queue.Queue
LOG = minimal_logger(__name__)
class TraditionalHealthDataPoller(DataPoller):
def assemble_environment_data(
self,
ids_of_all_instances,
instances_registered_with_elb
):
total_instances = len(ids_of_all_instances)
total_in_service = 0
for instance_state in instances_registered_with_elb:
if instance_state['State'] == statics.ec2_instance_statuses.IN_SERVICE:
total_in_service += 1
env = elasticbeanstalk.get_environment(app_name=self.app_name, env_name=self.env_name)
return {
'EnvironmentName': env.name,
'Color': env.health,
'Status': env.status,
'Total': total_instances,
'InService': total_in_service,
'Other': total_instances - total_in_service,
'RefreshedAt': _datetime_utcnow_wrapper()
}
def get_instance_health(self, instance_states):
instance_healths = []
for instance_state in instance_states:
instance = {
'id': instance_state['InstanceId'],
'state': instance_state['State'],
'description': instance_state['Description']
}
ec2_health = ec2.describe_instance(instance['id'])
instance['health'] = ec2_health['State']['Name']
instance_healths.append(instance)
return instance_healths
def get_health_information_of_instance_not_associated_with_elb(
self,
ids_of_all_instances,
instances_registered_with_elb
):
instance_healths = []
ids_of_all_instances = set(ids_of_all_instances)
ids_of_instances_registered_with_elb = set([x['InstanceId'] for x in instances_registered_with_elb])
for instance_id in list(ids_of_all_instances - ids_of_instances_registered_with_elb):
instance = dict([('id', instance_id)])
instance['description'] = 'N/A (Not registered with Load Balancer)'
instance['state'] = 'n/a'
ec2_health = ec2.describe_instance(instance_id)
instance['health'] = ec2_health['State']['Name']
instance_healths.append(instance)
return instance_healths
def get_instance_states(self, load_balancers):
if not load_balancers:
return []
load_balancer_name = load_balancers[0]['Name']
return self.get_load_balancer_instance_states(load_balancer_name)
def get_load_balancer_instance_states(self, load_balancer_name):
if elb.is_classic_load_balancer(load_balancer_name):
instance_states = elb.get_health_of_instances(load_balancer_name)
else:
load_balancer_arn = load_balancer_name
elbv2_target_groups = elbv2.get_target_groups_for_load_balancer(
load_balancer_arn=load_balancer_arn
)
target_group_arns = [
target_group['TargetGroupArn']
for target_group in elbv2_target_groups
]
instance_states = elbv2.get_instance_healths_from_target_groups(target_group_arns)
return instance_states
def _get_health_data(self):
env_dict = elasticbeanstalk.get_environment_resources(self.env_name)
environment_resources = env_dict['EnvironmentResources']
instances_registered_with_elb = self.get_instance_states(environment_resources.get('LoadBalancers'))
ids_of_all_instances = [instance['Id'] for instance in environment_resources.get('Instances', [])]
all_instances = (
self.get_instance_health(instances_registered_with_elb)
+
self.get_health_information_of_instance_not_associated_with_elb(
ids_of_all_instances,
instances_registered_with_elb
)
)
return {
'instances': all_instances,
'environment': self.assemble_environment_data(ids_of_all_instances, instances_registered_with_elb)
}
class TraditionalHealthScreen(Screen):
def __init__(self):
super(TraditionalHealthScreen, self).__init__()
self.empty_row = 3
def draw_banner_info_lines(self, lines, data):
if lines > 2:
term.echo_line('instances:',
io.bold(data.get('Total', 0)), 'Total,',
io.bold(data.get('InService', 0)), 'InService,',
io.bold(data.get('Other', 0)), 'Other',
)
lines -= 1
if lines > 2:
status = data.get('Status', 'Unknown')
term.echo_line(' Status:', io.bold(status),
'Health', io.bold(data.get('Color', 'Grey')))
lines -= 1
return lines
def _datetime_utcnow_wrapper():
return utils.datetime_utcnow()