putpaws 0.0.7 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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