ecs_compose 0.1.0.pre23 → 0.1.0.pre26

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
  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