require 'aws-sdk' require 'highline' # Context module Contexto # ECS class class Contextualize attr_reader :display, :cluster, :service, :container, :connection_type def initialize(params = {}) @cluster = params.fetch(:cluster) if params[:cluster] @service = params.fetch(:service) if params[:service] @container = params.fetch(:container) if params[:container] @connection_type = params.fetch(:connection_type) if params[:connection_type] @display = Contexto::Display.new end def run show if (connection_type && container) connect_to_endpoint elsif container prompt_endpoint end end def show if !cluster show_clusters return elsif cluster show_cluster puts "\n" end if !service show_services return elsif service puts "\n" show_service end if !container show_tasks return elsif container puts "\n" show_tasks(container) end end def connect task = describe_tasks ec2_instance_id = describe_container_instance(task[:container_instance_arn]) Contexto::SSH.new(describe_instances(ec2_instance_id), cluster, service, container) end def connect_to_endpoint connnect.connection_type.to_sym return end def prompt_endpoint cli = HighLine.new cli.choose do |menu| puts "\n" menu.header = "Do you want to connect to container #{container}'s? " menu.prompt = "Please choose a connection type? " menu.choice(:console) { connect.console } menu.choice(:bash) { connect.bash } menu.choice(:ssh) { connect.ssh } menu.choice(:nah) { return } end end def show_clusters title = "Clusters" headings = %w(Name) clusters = list_clusters rows = [] clusters.each do |cluster| rows << [cluster.split('/')[-1]] end @display.create_display(title, headings, rows) end def show_cluster title = "Cluster #{cluster}" headings = %w(Name Status Instances Services RunningTasks PendingTasks) cluster = describe_clusters rows = [] rows << [cluster[:cluster_name], cluster[:status], cluster[:registered_container_instances_count], cluster[:active_services_count], cluster[:running_tasks_count], cluster[:pending_tasks_count]] @display.create_display(title, headings, rows) end def show_services title = "Services" headings = %w(Name) services = list_services rows = [] services.each do |service| rows << [service.split('/')[-1]] end @display.create_display(title, headings, rows) end def show_service title = "Service #{service}" headings = %w(Name Status Desired Running Pending) service = describe_services rows = [] rows << [service[:service_name], service[:status], service[:desired_count], service[:running_count], service[:pending_count]] @display.create_display(title, headings, rows) rescue Aws::ECS::Errors::ServiceNotFoundException puts 'Service not found' end def show_tasks(container = '') task = describe_tasks if container containers = task[:containers].select { |c| container == c[:name] } else containers = task[:containers] end ec2_instance_id = describe_container_instance(task[:container_instance_arn]) title = 'Containers' headings = %w(Container Status IP) rows = [] containers.each do |container| rows << [container[:name], container[:last_status], describe_instances(ec2_instance_id)] end @display.create_display(title, headings, rows) end def list_clusters resp = ecs_client.list_clusters resp.cluster_arns end def describe_clusters resp = ecs_client.describe_clusters( clusters: [ cluster ] ) resp.clusters[0].to_h end def list_services resp = ecs_client.list_services( cluster: cluster ) resp.service_arns end def describe_services resp = ecs_client.describe_services( cluster: cluster, services: [ service ] ) resp.services[0].to_h end def describe_tasks resp = ecs_client.describe_tasks( cluster: cluster, tasks: [task_arn] ) resp.tasks[0].to_h end def task_arn resp = ecs_client.list_tasks( cluster: cluster, service_name: service ) resp.task_arns[0] end def describe_container_instance(container_instance_arn) resp = ecs_client.describe_container_instances( cluster: cluster, container_instances: [ container_instance_arn ] ) resp.container_instances[0].ec2_instance_id end def describe_instances(ec2_instance_id) resp = ec2_client.describe_instances( instance_ids: [ec2_instance_id] ) resp.reservations[0].instances[0].private_ip_address end def region_name ENV['AWS_REGION'] || 'us-east-1' end def ecs_client Aws::ECS::Client.new(region: region_name.to_s) end def ec2_client Aws::EC2::Client.new(region: region_name.to_s) end end end