putpaws 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ba984b5ce0261d5c757b4112e6d849aa0815ded01898ee9a25f42cebbb4254f
4
- data.tar.gz: e3b2871eacd65cd2d9904cd09090fce6a8d6fa2e55a227b385a2acbeb11c7c4f
3
+ metadata.gz: 3af9788e3c54a5647c912f45ee76b78691c7f1ac7f7654e6af7b7f3ce51b16f4
4
+ data.tar.gz: 51d6ea019d08c1139e3a865743d4435a304125a3a3b7ee2052332fc83aa170a3
5
5
  SHA512:
6
- metadata.gz: 7c2a4f49328c01dccf7a8efaa9bbdcb0fda07fe1fd68d2632cb6043329401f9059378ac0ed90d3211dc3d4dfcadefc2fe747dd494ecd9f0dae52681ffa5ef9d5
7
- data.tar.gz: acdad73a867e604275325d95c30d3b85f7b784b753cc4461d2838a385ac1b5b0f33cf93c87ecff58e778325a9416baad8994125c1b9108f803418ec7ee74edeb
6
+ metadata.gz: 26c390300f9e4cb4fc2a970bbfbbc762e2de2bcfcd3fdb50ed8128e065caacecc99572e6f447ef244cb4c51a1cb4f844c0cc2a14aac361b678dc1e0b7ed20d54
7
+ data.tar.gz: 3370e8ffe872b93910f951f12c29447b28ca411062d31eb3281740b786297505cc6c12408f11f780d10eefdc57bc4d58b3b0a381079eef6ea56d6b312021f4f8
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Put your paws up!!
2
+
3
+ ## Example
4
+
5
+ ### ECS
6
+
7
+ Attach to staging specific container
8
+
9
+ ```
10
+ bundle exec putpaws awesome-api-staging ecs:attach container=app
11
+ ```
12
+
13
+ Run port forwarding session through specific container
14
+
15
+ ```
16
+ bundle exec putpaws awesome-api-staging ecs:forward container=app remote=example-rds-host:3306 local=:1050
17
+ # local=:1050 is optional by the way, then random number is selected.
18
+ # Please check standard output in your shell for the auto-generated local port.
19
+
20
+ # You can access specified remote host with subsequent command in another shell like:
21
+ mysql -u awesome_user -p --port 1050 -h 127.0.0.1
22
+ ```
23
+
24
+ ### CloudWatch Logs
25
+
26
+ `tail -f`
27
+
28
+ ```
29
+ bundle exec putpaws awesome-api-staging log:tailf
30
+ ```
31
+
32
+ Find logs between specific date range using time symbol
33
+
34
+ - `s`: second
35
+ - `m`: minute
36
+ - `h`: hour
37
+ - `d`: day
38
+ - `w`: week
39
+
40
+ ```
41
+ # Find logs since 2 hours ago
42
+ bundle exec putpaws awesome-api-staging log:tailf since=2h
43
+
44
+ # Find logs since 1 day ago for 3 hours
45
+ bundle exec putpaws awesome-api-staging log:tail since=1d for=3h
46
+ ```
47
+
48
+ ## Set up
49
+
50
+ ```
51
+ gem 'putpaws'
52
+ ```
53
+
54
+ ## Setting Example
55
+
56
+ `.putpaws/application.json`
57
+
58
+ ```
59
+ {
60
+ "awesome-api-staging": {
61
+ "region": "ap-northeast-1",
62
+ "cluster": "cluster-staging",
63
+ "service": null,
64
+ "task_name_prefix": "awesome-api",
65
+ "log_group_prefix": "/ecs/awesome/awesome-api-staging",
66
+ "log_region": null,
67
+ "build_log_group_prefix": "/aws/codebuild/awesome-api-staging",
68
+ "build_project_name_prefix": "awesome-api-staging"
69
+ },
70
+ "awesome-api-production": {
71
+ "region": "ap-northeast-1",
72
+ "cluster": "cluster-production",
73
+ "service": null,
74
+ "task_name_prefix": "awesome-api",
75
+ "log_group_prefix": "/ecs/awesome/awesome-api-production",
76
+ "log_region": null
77
+ }
78
+ }
79
+ ```
data/lib/Putpawsfile CHANGED
@@ -4,4 +4,5 @@ require "putpaws/setup"
4
4
  require "putpaws/hello"
5
5
  require "putpaws/ecs/ecs_task"
6
6
  require "putpaws/cloud_watch/log_task"
7
- require "putpaws/scheduler/scheduler_task"
7
+ require "putpaws/scheduler/scheduler_task"
8
+ require "putpaws/code_build/build_task"
@@ -6,7 +6,7 @@ class Putpaws::ApplicationConfig < Struct.new(
6
6
  :name, :region,
7
7
  :cluster, :service, :task_name_prefix, :ecs_region,
8
8
  :log_group_prefix, :log_region,
9
- :build_project, :build_log_group_prefix, :build_region,
9
+ :build_project_name_prefix, :build_log_group_prefix, :build_region,
10
10
  :schedules,
11
11
  keyword_init: true)
12
12
  def self.load(path_prefix: '.putpaws')
@@ -59,4 +59,11 @@ class Putpaws::ApplicationConfig < Struct.new(
59
59
  def schedules
60
60
  @schedules ||= (self[:schedules] || []).map{|x| Putpaws::ScheduleConfig.find(x)}.compact
61
61
  end
62
+
63
+ def codebuild_command_params
64
+ {
65
+ region: build_region || region,
66
+ project_name_prefix: build_project_name_prefix,
67
+ }
68
+ end
62
69
  end
@@ -0,0 +1 @@
1
+ load File.expand_path("../tasks/build_task.rake", __FILE__)
@@ -0,0 +1,57 @@
1
+ require 'aws-sdk-codebuild'
2
+ # require 'aws-sdk-ssm'
3
+
4
+ module Putpaws::CodeBuild
5
+ class ProjectCommand
6
+ def self.config(config)
7
+ new(**config.codebuild_command_params)
8
+ end
9
+
10
+ attr_reader :codebuild_client
11
+ attr_reader :region, :project_name_prefix
12
+ attr_accessor :codebuild_project
13
+ def initialize(region:, project_name_prefix: nil)
14
+ @codebuild_client = Aws::CodeBuild::Client.new({region: region})
15
+ @region = region
16
+ @project_name_prefix = project_name_prefix
17
+ @codebuild_project = nil
18
+ end
19
+
20
+ def list_codebuild_projects
21
+ res = codebuild_client.batch_get_projects(names: [project_name_prefix])
22
+ res.projects.select{|pr| pr.name.start_with?(project_name_prefix)}
23
+ end
24
+
25
+ def start_build_with_specific_version(source_version:, environment_variables: {}, buildspec_override: nil, artifacts_override: nil)
26
+ current_variables = codebuild_project.environment.environment_variables.map{|x| [x.name, {type: x.type, value: x.value}]}.to_h
27
+ new_variables = environment_variables.reduce(current_variables) {|acc,(k,v)| acc[k] = {type: 'PLANTTEXT', value: v}}
28
+ environment_variables_override = new_variables.map{|k,v| v.merge(name: k)}
29
+ params = {
30
+ project_name: codebuild_project.name,
31
+ source_version: source_version,
32
+ environment_variables_override: environment_variables_override,
33
+ }
34
+ if buildspec_override
35
+ params = params.merge(buildspec_override: buildspec_override)
36
+ end
37
+ if artifacts_override
38
+ params = params.merge(artifacts_override: artifacts_override)
39
+ end
40
+
41
+ codebuild_client.start_build(**params)
42
+ end
43
+
44
+ def build_source_version(type:, version:)
45
+ type = type.to_sym
46
+ if type == :branch
47
+ "refs/heads/#{version}"
48
+ elsif type == :tag
49
+ "refs/tags/#{version}"
50
+ elsif type == :commit_id
51
+ version
52
+ else
53
+ raise "Please specify valid type: branch or tag or commit_id"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,39 @@
1
+ require "putpaws/prompt"
2
+ require "putpaws/code_build/project_command"
3
+
4
+ namespace :code_build do
5
+ desc "Set CodeBuild project."
6
+ task :set_project do
7
+ aws = Putpaws::CodeBuild::ProjectCommand.config(fetch(:app))
8
+ codebuild_projects = aws.list_codebuild_projects.map{|x|
9
+ [x.name, x]
10
+ }.to_h
11
+ prompt = Putpaws::Prompt.safe
12
+ selected = prompt.select("Choose a project you're going to operate", codebuild_projects.keys)
13
+ codebuild_project = codebuild_projects[selected]
14
+
15
+ set :codebuild_project, codebuild_project
16
+ end
17
+
18
+ desc "Start build."
19
+ task build: :set_project do
20
+ aws = Putpaws::CodeBuild::ProjectCommand.config(fetch(:app))
21
+
22
+ source_version = if ENV['branch']
23
+ aws.build_source_version(type: :branch, version: ENV['branch'])
24
+ elsif ENV['tag']
25
+ aws.build_source_version(type: :tag, version: ENV['tag'])
26
+ elsif ENV['commit_id']
27
+ aws.build_source_version(type: :commit_id, version: ENV['commit_id'])
28
+ else
29
+ raise "Please specify required parameter like: branch=main or tag=release/20240601 or commit_id=0f0f0f0f"
30
+ end
31
+ codebuild_project = fetch(:codebuild_project)
32
+ aws.codebuild_project = codebuild_project
33
+ aws.start_build_with_specific_version(
34
+ source_version: source_version,
35
+ environment_variables: ENV['env'] ? JSON.parse(ENV['env']) : {},
36
+ buildspec_override: ENV['buildspec']
37
+ )
38
+ end
39
+ end
@@ -1,4 +1,5 @@
1
1
  require 'aws-sdk-ecs'
2
+ require 'aws-sdk-ssm'
2
3
 
3
4
  module Putpaws::Ecs
4
5
  class TaskCommand
@@ -27,11 +28,35 @@ module Putpaws::Ecs
27
28
  }
28
29
  end
29
30
 
30
- def get_attach_command(container: 'app')
31
+ def get_session_target(container: 'app')
31
32
  raise "ECS Task Not Set" unless ecs_task
32
33
  ctn = ecs_task.containers.detect{|c| c.name == container}
33
34
  task_id = ecs_task.task_arn.split('/').last
34
35
  raise "Container: #{container} not found" unless ctn
36
+ "ecs:#{cluster}_#{task_id}_#{ctn.runtime_id}"
37
+ end
38
+
39
+ def get_port_forwarding_command(container: nil, remote_port:, remote_host:, local_port: nil)
40
+ container ||= 'app'
41
+ target = get_session_target(container: container)
42
+ ssm_client = Aws::SSM::Client.new({region: region})
43
+ local_port ||= (1050..1079).map(&:to_s).shuffle.first
44
+ puts "Starting to use local port: #{local_port}"
45
+ res = ssm_client.start_session({
46
+ target: target,
47
+ document_name: "AWS-StartPortForwardingSessionToRemoteHost",
48
+ parameters: {
49
+ portNumber: [remote_port],
50
+ localPortNumber: [local_port],
51
+ host: [remote_host]
52
+ }
53
+ })
54
+ build_session_manager_plugin_command(session: res, target: target)
55
+ end
56
+
57
+ def get_attach_command(container: nil)
58
+ container ||= 'app'
59
+ target = get_session_target(container: container)
35
60
  res = ecs_client.execute_command({
36
61
  cluster: cluster,
37
62
  container: container,
@@ -39,17 +64,26 @@ module Putpaws::Ecs
39
64
  interactive: true,
40
65
  task: ecs_task.task_arn,
41
66
  })
67
+ build_session_manager_plugin_command(session: res.session, target: target)
68
+ end
42
69
 
70
+ def build_session_manager_plugin_command(session:, target:)
43
71
  ssm_region = ENV['AWS_REGION_SSM'] || @region
44
-
72
+
45
73
  # https://github.com/aws/aws-cli/blob/2a6136010d8656a605d41d1e7b5fdab3c2930cad/awscli/customizations/ecs/executecommand.py#L105
46
- session_json = {
47
- "SessionId" => res.session.session_id,
48
- "StreamUrl" => res.session.stream_url,
49
- "TokenValue" => res.session.token_value,
50
- }.to_json
74
+ session_json = if session.respond_to?(:session_id)
75
+ {
76
+ "SessionId" => session.session_id,
77
+ "StreamUrl" => session.stream_url,
78
+ "TokenValue" => session.token_value,
79
+ }.to_json
80
+ elsif session.is_a?(Hash)
81
+ session.to_json
82
+ else
83
+ session
84
+ end
51
85
  target_json = {
52
- "Target" => "ecs:#{cluster}_#{task_id}_#{ctn.runtime_id}"
86
+ "Target" => target
53
87
  }.to_json
54
88
  cmd = [
55
89
  "session-manager-plugin",
@@ -22,7 +22,28 @@ namespace :ecs do
22
22
  ecs_task = fetch(:ecs_task)
23
23
  aws = Putpaws::Ecs::TaskCommand.config(fetch(:app))
24
24
  aws.ecs_task = ecs_task
25
- cmd = aws.get_attach_command
25
+ cmd = aws.get_attach_command(container: ENV['container'])
26
+ puts cmd
27
+ system(cmd)
28
+ end
29
+
30
+ desc "Run port forwarding session. You need to enable ECS Exec on a specified task and also install session-manager-plugin."
31
+ task forward: :set_task do
32
+ ecs_task = fetch(:ecs_task)
33
+ aws = Putpaws::Ecs::TaskCommand.config(fetch(:app))
34
+ aws.ecs_task = ecs_task
35
+
36
+ remote_host, remote_port = (ENV['remote'] || '').split(':').map(&:strip)
37
+ _, local_port = (ENV['local'] || '').split(':').map(&:strip)
38
+ if remote_host.nil? or remote_port.nil?
39
+ raise "Remote Host, Port is required: (Ex) remote=192.168.1.1:80"
40
+ end
41
+ cmd = aws.get_port_forwarding_command(
42
+ container: ENV['container'],
43
+ remote_host: remote_host,
44
+ remote_port: remote_port,
45
+ local_port: local_port
46
+ )
26
47
  puts cmd
27
48
  system(cmd)
28
49
  end
@@ -1,3 +1,3 @@
1
1
  module Putpaws
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: putpaws
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - metheglin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-18 00:00:00.000000000 Z
11
+ date: 2024-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk-ssm
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: aws-sdk-ecs
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: aws-sdk-codebuild
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: aws fargate based infra management
84
112
  email: pigmybank@gmail.com
85
113
  executables:
@@ -87,6 +115,7 @@ executables:
87
115
  extensions: []
88
116
  extra_rdoc_files: []
89
117
  files:
118
+ - README.md
90
119
  - bin/putpaws
91
120
  - lib/Putpawsfile
92
121
  - lib/putpaws.rb
@@ -97,6 +126,9 @@ files:
97
126
  - lib/putpaws/cloud_watch/log_command.rb
98
127
  - lib/putpaws/cloud_watch/log_task.rb
99
128
  - lib/putpaws/cloud_watch/tasks/log_task.rake
129
+ - lib/putpaws/code_build/build_task.rb
130
+ - lib/putpaws/code_build/project_command.rb
131
+ - lib/putpaws/code_build/tasks/build_task.rake
100
132
  - lib/putpaws/dsl.rb
101
133
  - lib/putpaws/ecs/ecs_task.rb
102
134
  - lib/putpaws/ecs/task_command.rb