Class: Putpaws::Ecs::TaskCommand
- Inherits:
-
Object
- Object
- Putpaws::Ecs::TaskCommand
- Defined in:
- lib/putpaws/ecs/task_command.rb
Instance Attribute Summary collapse
-
#cluster ⇒ Object
readonly
Returns the value of attribute cluster.
-
#ecs_client ⇒ Object
readonly
Returns the value of attribute ecs_client.
-
#ecs_task ⇒ Object
Returns the value of attribute ecs_task.
-
#region ⇒ Object
readonly
Returns the value of attribute region.
-
#service ⇒ Object
readonly
Returns the value of attribute service.
-
#task_name_prefix ⇒ Object
readonly
Returns the value of attribute task_name_prefix.
Class Method Summary collapse
Instance Method Summary collapse
-
#build_session_manager_plugin_command(session:, target:) ⇒ Object
Returns an argument array so that callers can spawn session-manager-plugin without a shell like
system(*cmd). - #get_attach_command(container: nil) ⇒ Object
- #get_port_forwarding_command(container: nil, remote_port:, remote_host:, local_port: nil) ⇒ Object
- #get_session_target(container: 'app') ⇒ Object
-
#initialize(region:, cluster:, service: nil, task_name_prefix: nil) ⇒ TaskCommand
constructor
A new instance of TaskCommand.
- #list_ecs_services ⇒ Object
- #list_ecs_tasks ⇒ Object
- #local_port_available?(port) ⇒ Boolean
- #resolve_local_port(local_port) ⇒ Object
- #update_ecs_service(service:, desired_count: nil, task_definition: nil) ⇒ Object
- #wait_ecs_service_stable(service:, timeout: 600) ⇒ Object
Constructor Details
#initialize(region:, cluster:, service: nil, task_name_prefix: nil) ⇒ TaskCommand
Returns a new instance of TaskCommand.
14 15 16 17 18 19 20 21 |
# File 'lib/putpaws/ecs/task_command.rb', line 14 def initialize(region:, cluster:, service: nil, task_name_prefix: nil) @ecs_client = Aws::ECS::Client.new({region: region}) @region = region @cluster = cluster @service = service @task_name_prefix = task_name_prefix @ecs_task = nil end |
Instance Attribute Details
#cluster ⇒ Object (readonly)
Returns the value of attribute cluster.
12 13 14 |
# File 'lib/putpaws/ecs/task_command.rb', line 12 def cluster @cluster end |
#ecs_client ⇒ Object (readonly)
Returns the value of attribute ecs_client.
11 12 13 |
# File 'lib/putpaws/ecs/task_command.rb', line 11 def ecs_client @ecs_client end |
#ecs_task ⇒ Object
Returns the value of attribute ecs_task.
13 14 15 |
# File 'lib/putpaws/ecs/task_command.rb', line 13 def ecs_task @ecs_task end |
#region ⇒ Object (readonly)
Returns the value of attribute region.
12 13 14 |
# File 'lib/putpaws/ecs/task_command.rb', line 12 def region @region end |
#service ⇒ Object (readonly)
Returns the value of attribute service.
12 13 14 |
# File 'lib/putpaws/ecs/task_command.rb', line 12 def service @service end |
#task_name_prefix ⇒ Object (readonly)
Returns the value of attribute task_name_prefix.
12 13 14 |
# File 'lib/putpaws/ecs/task_command.rb', line 12 def task_name_prefix @task_name_prefix end |
Class Method Details
.config(config) ⇒ Object
7 8 9 |
# File 'lib/putpaws/ecs/task_command.rb', line 7 def self.config(config) new(**config.ecs_command_params) end |
Instance Method Details
#build_session_manager_plugin_command(session:, target:) ⇒ Object
Returns an argument array so that callers can spawn session-manager-plugin
without a shell like system(*cmd).
https://github.com/aws/aws-cli/blob/2a6136010d8656a605d41d1e7b5fdab3c2930cad/awscli/customizations/ecs/executecommand.py#L105
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/putpaws/ecs/task_command.rb', line 126 def build_session_manager_plugin_command(session:, target:) ssm_region = ENV['AWS_REGION_SSM'] || @region session_json = if session.respond_to?(:session_id) { "SessionId" => session.session_id, "StreamUrl" => session.stream_url, "TokenValue" => session.token_value, }.to_json elsif session.is_a?(Hash) session.to_json else session end target_json = { "Target" => target }.to_json [ "session-manager-plugin", session_json, @region, "StartSession", ENV['AWS_PROFILE'].to_s, target_json, "https://ssm.#{ssm_region}.amazonaws.com" ] end |
#get_attach_command(container: nil) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/putpaws/ecs/task_command.rb', line 110 def get_attach_command(container: nil) container ||= 'app' target = get_session_target(container: container) res = ecs_client.execute_command({ cluster: cluster, container: container, command: '/bin/bash', interactive: true, task: ecs_task.task_arn, }) build_session_manager_plugin_command(session: res.session, target: target) end |
#get_port_forwarding_command(container: nil, remote_port:, remote_host:, local_port: nil) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/putpaws/ecs/task_command.rb', line 92 def get_port_forwarding_command(container: nil, remote_port:, remote_host:, local_port: nil) container ||= 'app' target = get_session_target(container: container) ssm_client = Aws::SSM::Client.new({region: region}) local_port = resolve_local_port(local_port) puts "Starting to use local port: #{local_port}" res = ssm_client.start_session({ target: target, document_name: "AWS-StartPortForwardingSessionToRemoteHost", parameters: { portNumber: [remote_port], localPortNumber: [local_port], host: [remote_host] } }) build_session_manager_plugin_command(session: res, target: target) end |
#get_session_target(container: 'app') ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/putpaws/ecs/task_command.rb', line 64 def get_session_target(container: 'app') raise "ECS Task Not Set" unless ecs_task ctn = ecs_task.containers.detect{|c| c.name == container} task_id = ecs_task.task_arn.split('/').last raise "Container: #{container} not found" unless ctn "ecs:#{cluster}_#{task_id}_#{ctn.runtime_id}" end |
#list_ecs_services ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/putpaws/ecs/task_command.rb', line 34 def list_ecs_services res = ecs_client.list_services(cluster: cluster, max_results: 100) return [] if res.service_arns.empty? res = ecs_client.describe_services(cluster: cluster, services: res.service_arns) services = res.services.select{|s| s.status == 'ACTIVE'} return services unless task_name_prefix filtered = services.select{|s| s.service_name.start_with?(task_name_prefix)} filtered.empty? ? services : filtered end |
#list_ecs_tasks ⇒ Object
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/putpaws/ecs/task_command.rb', line 23 def list_ecs_tasks res = ecs_client.list_tasks(cluster: cluster) return [] if res.task_arns.empty? res = ecs_client.describe_tasks(tasks: res.task_arns, cluster: cluster) return res.tasks unless task_name_prefix res.tasks.select{|t| _, name = t.task_definition_arn.split('task-definition/') name.start_with?(task_name_prefix) } end |
#local_port_available?(port) ⇒ Boolean
72 73 74 75 76 77 |
# File 'lib/putpaws/ecs/task_command.rb', line 72 def local_port_available?(port) TCPServer.new('127.0.0.1', port.to_i).close true rescue Errno::EADDRINUSE, Errno::EACCES false end |
#resolve_local_port(local_port) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/putpaws/ecs/task_command.rb', line 79 def resolve_local_port(local_port) if local_port unless local_port_available?(local_port) raise "Local port #{local_port} is already in use" end local_port.to_s else port = (1050..1079).to_a.shuffle.detect{|p| local_port_available?(p)} raise "No available local port between 1050 and 1079. Please specify one like: local=:8080" unless port port.to_s end end |
#update_ecs_service(service:, desired_count: nil, task_definition: nil) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/putpaws/ecs/task_command.rb', line 44 def update_ecs_service(service:, desired_count: nil, task_definition: nil) params = { cluster: cluster, service: service, force_new_deployment: true, } params[:desired_count] = desired_count.to_i if desired_count params[:task_definition] = task_definition if task_definition res = ecs_client.update_service(**params) res.service end |
#wait_ecs_service_stable(service:, timeout: 600) ⇒ Object
56 57 58 59 60 61 62 |
# File 'lib/putpaws/ecs/task_command.rb', line 56 def wait_ecs_service_stable(service:, timeout: 600) ecs_client.wait_until( :services_stable, {cluster: cluster, services: [service]}, {delay: 15, max_attempts: (timeout / 15.0).ceil} ) end |