ecs_compose 0.1.0.pre23 → 0.1.0.pre26

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
  SHA1:
3
- metadata.gz: 44652fed3e1b8e9b49392f9d042291e8cbc9ed67
4
- data.tar.gz: 017482c7d7f0937820b20e243562de13e4a742be
3
+ metadata.gz: be50de9cd4fa54757a557a57ad8f30a6e600acc1
4
+ data.tar.gz: 5b0ddfed2870445d82fee42e8ab325f7c4ee0f4e
5
5
  SHA512:
6
- metadata.gz: 38cf507deb32f24f41bde413dde811af98dac5e82bd58cb8b955d4483f65ec9da18399ae7cad0823c5c12e033cd9a2c91f1ded5d5268ed4eb1f3cc4fde6d70c2
7
- data.tar.gz: 48962ba33465cecbd19e8bb01bc1c767c202b3a51da743296751eb15b74cdf9a684534f753699f4c915f4c7805143551da18620e52fb1c8a0103d4ffbfa05a41
6
+ metadata.gz: 98fed5d3058dd67d385426ff19c10425ee2b99ec4239ab99ceaee3f38695409cff0a0c7695776a4554fe99fe67de031d57391bf6988b98b9c08ebfac206de57f
7
+ data.tar.gz: b58f20d5927e3c4092b338ab931f257046ce47286ebcb28e839fdbc7cbb3f740eb20049d02180cdc916742b6c8f5bd46e35797d03bb7a4271247884427738f31
data/ecs_compose.gemspec CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency "docopt", "~> 0.5.0"
31
31
  spec.add_dependency "colorize", "~> 0.7.7"
32
32
 
33
+ spec.add_development_dependency "vault", "~> 0.1.5"
33
34
  spec.add_development_dependency "bundler", "~> 1.10"
34
35
  spec.add_development_dependency "rake", "~> 10.0"
35
36
  spec.add_development_dependency "rspec"
@@ -38,6 +38,7 @@ module EcsCompose
38
38
  td = sort_recursively(td)
39
39
  td.delete("taskDefinitionArn")
40
40
  td.delete("revision")
41
+ Plugins.plugins.each {|p| p.normalize_task_definition!(td) }
41
42
  td
42
43
  end
43
44
  end
@@ -0,0 +1,26 @@
1
+ module EcsCompose
2
+ module Plugins
3
+ # A list of all available plugins.
4
+ AVAILABLE_PLUGINS = []
5
+
6
+ # Subclass this class and add it to `AVAILABLE_PLUGINS` to extend
7
+ # `ecs_compose`.
8
+ class Plugin
9
+ # Does this plugin apply
10
+ def self.enabled?
11
+ false
12
+ end
13
+
14
+ # Normalize a task definition for comparison. This may remove
15
+ # certain environment variables, for example, that are allowed to
16
+ # vary from one deploy to the next.
17
+ def normalize_task_definition!(taskdef)
18
+ end
19
+
20
+ # Called when we decide to skip a deploy because the previous version
21
+ # of the software appears to still be valid.
22
+ def notify_skipping_deploy(old, new)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ module EcsCompose
2
+ module Plugins
3
+
4
+ class VaultPlugin
5
+ # We're enabled if we know about a vault server.
6
+ def self.enabled?
7
+ ENV.has_key?('VAULT_ADDR') && ENV.has_key?('VAULT_MASTER_TOKEN')
8
+ end
9
+
10
+ # Make sure that vault is loaded and configured.
11
+ def initialize
12
+ begin
13
+ require 'vault' unless defined?(Vault)
14
+ rescue
15
+ STDERR.puts("VAULT_ADDR defined, but `vault` gem not available")
16
+ exit(1)
17
+ end
18
+ Vault.address = ENV.fetch('VAULT_ADDR')
19
+ Vault.token = ENV.fetch('VAULT_MASTER_TOKEN')
20
+ end
21
+
22
+ # Normalize a task definition for comparison by removing VAULT_TOKEN
23
+ # from each of the containers' environments.
24
+ def normalize_task_definition!(taskdef)
25
+ containers = taskdef.fetch("containerDefinitions", [])
26
+ containers.each do |container|
27
+ env = container.fetch("environment", [])
28
+ env.reject! {|v| v.fetch("name") == "VAULT_TOKEN" }
29
+ end
30
+ end
31
+
32
+ # Called when we decide to skip a deploy because the previous version
33
+ # of the software appears to still be valid.
34
+ def notify_skipping_deploy(old, new)
35
+ tokens = old
36
+ .fetch("containerDefinitions", [])
37
+ .map {|c| c.fetch("environment", []) }
38
+ .flatten
39
+ .select {|var| var.fetch("name") == "VAULT_TOKEN" }
40
+ .map {|var| var.fetch("value") }
41
+ puts "Renewing #{tokens.length} vault tokens"
42
+ tokens.each {|tok| Vault.auth_token.renew(tok) }
43
+ end
44
+ end
45
+
46
+ AVAILABLE_PLUGINS << VaultPlugin
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ require "ecs_compose/plugins/plugin"
2
+ require "ecs_compose/plugins/vault_plugin"
3
+
4
+ module EcsCompose
5
+ # Plugins which allow ecs-compose to work better with various third-party
6
+ # tools.
7
+ module Plugins
8
+ # A list of all enabled plugins. Generated on demand to make it easier
9
+ # to work with test suites.
10
+ def self.plugins
11
+ AVAILABLE_PLUGINS.select {|p| p.enabled? }.map {|p| p.new }
12
+ end
13
+ end
14
+ end
15
+
@@ -21,22 +21,69 @@ module EcsCompose
21
21
  # add a new version of the task. Returns a string of the form
22
22
  # `"name:revision"` identifying the task we registered, or an existing
23
23
  # task with the same properties.
24
- def register
25
- existing = Ecs.describe_task_definition(@name).fetch("taskDefinition")
24
+ def register(deployed=nil)
25
+ # Describe the version we're currently running.
26
+ if deployed
27
+ existing = Ecs.describe_task_definition(deployed)
28
+ .fetch("taskDefinition")
29
+ else
30
+ existing = nil
31
+ end
32
+
33
+ # Register the new version. We always need to do this, so that we
34
+ # can compare two officially normalized versions of the same task,
35
+ # including any fields added by Amazon.
26
36
  new = register_new.fetch("taskDefinition")
27
- use =
28
- if Compare.task_definitions_match?(existing, new)
29
- existing
30
- else
31
- new
32
- end
33
- "#{use.fetch('family')}:#{use.fetch('revision')}"
37
+
38
+ # Decide whether we can re-use the existing registration.
39
+ if existing && Compare.task_definitions_match?(existing, new)
40
+ rev1 = "#{existing.fetch('family')}:#{existing.fetch('revision')}"
41
+ rev2 = "#{new.fetch('family')}:#{new.fetch('revision')}"
42
+ puts "Running copy of #{rev1} looks good; not updating to #{rev2}."
43
+ Plugins.plugins.each {|p| p.notify_skipping_deploy(existing, new) }
44
+ wanted = existing
45
+ else
46
+ wanted = new
47
+ end
48
+ "#{wanted.fetch('family')}:#{wanted.fetch('revision')}"
49
+ end
50
+
51
+ # Get the existing "PRIMARY" deployment for the ECS service
52
+ # corresponding to this task definition, and return it in
53
+ # `name:revision` format. Returns `nil` if it can't find a primary
54
+ # deployment.
55
+ def primary_deployment(cluster)
56
+ # Try to describe the existing service.
57
+ begin
58
+ service = Ecs.describe_services(cluster.name, [@name])
59
+ .fetch("services")[0]
60
+ rescue => e
61
+ puts <<EOD
62
+ Error: #{e}
63
+
64
+ Can't find an existing service '#{name}'. You'll probably need to
65
+ register one manually using the AWS console and set up any load balancers
66
+ you might need.
67
+ EOD
68
+ return nil
69
+ end
70
+
71
+ # Find the primary deployment.
72
+ deployment = service.fetch("deployments").find do |d|
73
+ d["status"] == "PRIMARY"
74
+ end
75
+ return nil if deployment.nil?
76
+
77
+ # Extract a task definition `name:revision`.
78
+ arn = deployment.fetch("taskDefinition")
79
+ arn.split('/').last
34
80
  end
35
81
 
36
82
  # Register this task definition with ECS, and update the corresponding
37
83
  # service.
38
84
  def update(cluster)
39
- Ecs.update_service(cluster.name, name, register)
85
+ deployed = primary_deployment(cluster)
86
+ Ecs.update_service(cluster.name, name, register(deployed))
40
87
  name
41
88
  end
42
89
 
data/lib/ecs_compose.rb CHANGED
@@ -7,6 +7,7 @@ require "ecs_compose/task_error"
7
7
  require "ecs_compose/cluster"
8
8
  require "ecs_compose/task_definition"
9
9
  require "ecs_compose/manifest"
10
+ require "ecs_compose/plugins"
10
11
  require "ecs_compose/compare"
11
12
 
12
13
  module EcsCompose
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecs_compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre23
4
+ version: 0.1.0.pre26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kidd
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-09 00:00:00.000000000 Z
11
+ date: 2015-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docopt
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.7.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: vault
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.5
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.5
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -110,6 +124,9 @@ files:
110
124
  - lib/ecs_compose/ecs.rb
111
125
  - lib/ecs_compose/json_generator.rb
112
126
  - lib/ecs_compose/manifest.rb
127
+ - lib/ecs_compose/plugins.rb
128
+ - lib/ecs_compose/plugins/plugin.rb
129
+ - lib/ecs_compose/plugins/vault_plugin.rb
113
130
  - lib/ecs_compose/service_error.rb
114
131
  - lib/ecs_compose/task_definition.rb
115
132
  - lib/ecs_compose/task_error.rb