leeroy_app 0.2.1 → 0.3.0

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: c0c28154a5624749bcca57645cc3f530ab6e52b1
4
- data.tar.gz: e82ec9e06da348ddaf2fb72c81fda77750be4bf4
3
+ metadata.gz: 901e04cff018388ce59ecc37cf0dda4f00e86505
4
+ data.tar.gz: 37df1f722a6ae265e6811b7a0b06c7ffa5615299
5
5
  SHA512:
6
- metadata.gz: a665431cc855c650c0f94783f459355f4923c348e616b622490fb4e5aa5fde557e8e930c12ab99807f8904dc2fb540f8c95c95f9db044bb7abb10cb4c2808f66
7
- data.tar.gz: 66e4028d1f596c70a8925e894eab3d88f9416e633fe9ef4c219e50fd58dbe53b2ecced9d30f9e598053e942e6c6990d43b54f17336b738a8464b905c898e4998
6
+ metadata.gz: 0716d6cbc37a332f7406fa82a86a93564dba0d3d7bc34c3118c4171202aad0f6b677431b4255c57b6adb1b5d8307b9f259089a84dd3586cedc52ce1cd9bda1f6
7
+ data.tar.gz: 901a20e7b8348230ee86bd16f9a95c1b79d12460f3a375fa20b612f73c9f2f89e53a5db9d6c79eda7b8af0fc087469ecc37037f3d8aa387a1e740982523ccf72
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ .rake_t_cache
3
4
  /.config
4
5
  /coverage/
5
6
  /InstalledFiles
data/.rdoc_options ADDED
@@ -0,0 +1,17 @@
1
+ --- !ruby/object:RDoc::Options
2
+ encoding: UTF-8
3
+ static_path: []
4
+ rdoc_include:
5
+ - .
6
+ charset: UTF-8
7
+ exclude:
8
+ hyperlink_all: false
9
+ line_numbers: true
10
+ main_page:
11
+ markup: markdown
12
+ page_dir:
13
+ show_hash: false
14
+ tab_width: 4
15
+ title:
16
+ visibility: :protected
17
+ webcvs:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- leeroy_app (0.2.1)
4
+ leeroy_app (0.3.0)
5
5
  awesome_print (~> 1.6)
6
6
  aws-sdk (~> 2)
7
7
  chronic (~> 0.10)
@@ -11,6 +11,7 @@ PATH
11
11
  multi_json (~> 1.11)
12
12
  rugged (~> 0.23)
13
13
  smart_polling (~> 1.0)
14
+ typesafe_enum (~> 0.1)
14
15
  yell (~> 2.0)
15
16
  yell-adapters-syslog (~> 2.0)
16
17
 
@@ -26,12 +27,12 @@ GEM
26
27
  rspec-expectations (>= 2.99)
27
28
  thor (~> 0.19)
28
29
  awesome_print (1.6.1)
29
- aws-sdk (2.2.20)
30
- aws-sdk-resources (= 2.2.20)
31
- aws-sdk-core (2.2.20)
30
+ aws-sdk (2.2.27)
31
+ aws-sdk-resources (= 2.2.27)
32
+ aws-sdk-core (2.2.27)
32
33
  jmespath (~> 1.0)
33
- aws-sdk-resources (2.2.20)
34
- aws-sdk-core (= 2.2.20)
34
+ aws-sdk-resources (2.2.27)
35
+ aws-sdk-core (= 2.2.27)
35
36
  builder (3.2.2)
36
37
  childprocess (0.5.9)
37
38
  ffi (~> 1.0, >= 1.0.11)
@@ -79,10 +80,11 @@ GEM
79
80
  diff-lcs (>= 1.2.0, < 2.0)
80
81
  rspec-support (~> 3.4.0)
81
82
  rspec-support (3.4.1)
82
- rugged (0.23.3)
83
+ rugged (0.24.0)
83
84
  slop (3.6.0)
84
85
  smart_polling (1.0.0)
85
86
  thor (0.19.1)
87
+ typesafe_enum (0.1.6)
86
88
  yell (2.0.5)
87
89
  yell-adapters-syslog (2.0.2)
88
90
  yell (~> 2.0)
data/leeroy.gemspec CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_runtime_dependency "multi_json", "~> 1.11"
38
38
  spec.add_runtime_dependency "rugged", "~> 0.23"
39
39
  spec.add_runtime_dependency "smart_polling", "~> 1.0"
40
+ spec.add_runtime_dependency "typesafe_enum", "~> 0.1"
40
41
  spec.add_runtime_dependency "yell", "~> 2.0"
41
42
  spec.add_runtime_dependency "yell-adapters-syslog", "~> 2.0"
42
43
  end
data/lib/leeroy/app.rb CHANGED
@@ -3,11 +3,13 @@
3
3
  require 'gli'
4
4
 
5
5
  require 'leeroy'
6
+ require 'leeroy/task/fixture'
6
7
  require 'leeroy/task/image'
7
8
  require 'leeroy/task/instantiate'
8
9
  require 'leeroy/task/terminate'
9
10
  require 'leeroy/task/sleep'
10
11
  require 'leeroy/task/stub'
12
+ require 'leeroy/types/fixture'
11
13
  require 'leeroy/types/phase'
12
14
 
13
15
  include GLI::App
@@ -16,7 +18,8 @@ module Leeroy
16
18
  module App
17
19
 
18
20
  # constants
19
- VALID_PHASE = Leeroy::Types::Phase::VALID_PHASE
21
+ VALID_PHASE = Leeroy::Types::Phase.to_a.collect {|x| x.value}
22
+ VALID_FIXTURE = Leeroy::Types::Fixture.to_a.collect {|x| x.value}
20
23
 
21
24
  program_desc 'Automate tasks with Jenkins'
22
25
 
@@ -54,7 +57,7 @@ module Leeroy
54
57
  c.action do |global_options,options,args|
55
58
  # validate input
56
59
  unless options[:phase].nil? or valid_phase.include?(options[:phase])
57
- help_now! "Valid arguments for '--phase' are: #{valid_phase.sort.join(',')}."
60
+ help_now! "Valid arguments for '--phase' are: #{valid_phase.join(',')}."
58
61
  end
59
62
 
60
63
  task = Leeroy::Task::Instantiate.new(global_options: global_options, options: options, args: args)
@@ -90,7 +93,7 @@ module Leeroy
90
93
  c.action do |global_options,options,args|
91
94
  # validate input
92
95
  unless options[:phase].nil? or valid_phase.include?(options[:phase])
93
- help_now! "Valid arguments for '--phase' are: #{valid_phase.sort.join(',')}."
96
+ help_now! "Valid arguments for '--phase' are: #{valid_phase.join(',')}."
94
97
  end
95
98
 
96
99
  # index must be nil or must look like a positive integer
@@ -108,6 +111,27 @@ module Leeroy
108
111
  end
109
112
  end
110
113
 
114
+ desc "Creates a fixture for a staging environment."
115
+ command :fixture do |c|
116
+
117
+ valid_fixture = VALID_FIXTURE
118
+ c.desc "Phase of deploy process for which to deploy (must be one of #{valid_fixture})."
119
+ c.flag [:f, :fixture], :must_match => valid_fixture
120
+
121
+ c.desc "Header template to be rendered before fixture template."
122
+ c.flag [:h, :header], :default_value => nil
123
+
124
+ c.action do |global_options,options,args|
125
+ # validate input
126
+ unless options[:fixture].nil? or valid_fixture.include?(options[:fixture])
127
+ help_now! "Valid arguments for '--fixture' are: #{valid_fixture.join(',')}."
128
+ end
129
+
130
+ task = Leeroy::Task::Fixture.new(global_options: global_options, options: options, args: args)
131
+ task.perform
132
+ end
133
+ end
134
+
111
135
  desc "Sleeps for some number of seconds."
112
136
  command :sleep do |c|
113
137
  c.desc "Number of seconds to sleep."
@@ -450,6 +450,30 @@ module Leeroy
450
450
  end
451
451
  end
452
452
 
453
+ def getSemaphore(semaphore)
454
+ begin
455
+ unless semaphore.kind_of?(Leeroy::Types::Semaphore)
456
+ semaphore = Leeroy::Types::Semaphore.new(semaphore)
457
+ end
458
+
459
+ run_params = Leeroy::Types::Mash.new
460
+ run_params.bucket = semaphore.bucket
461
+ run_params.key = semaphore.object
462
+
463
+ logger.debug "downloading #{semaphore}"
464
+ resp = s3Request(:get_object, run_params)
465
+
466
+ resp.body.string
467
+
468
+ rescue Aws::S3::Errors::NotFound => e
469
+ logger.debug "#{semaphore} not found"
470
+ nil
471
+
472
+ rescue StandardError => e
473
+ raise e
474
+ end
475
+ end
476
+
453
477
  end
454
478
  end
455
479
  end
@@ -23,7 +23,7 @@ module Leeroy
23
23
  logger.debug "app_name: #{app_name}"
24
24
 
25
25
  # build target depends on phase
26
- build_target = case phase
26
+ build_target = case phase.to_s
27
27
  when 'gold_master'
28
28
  'master'
29
29
  when 'application'
@@ -55,7 +55,7 @@ module Leeroy
55
55
  logger.debug "index provided: #{index}"
56
56
  else
57
57
  logger.debug "index not provided, calculating"
58
- phase = state.phase
58
+ phase = state.phase.to_s
59
59
 
60
60
  index = case phase
61
61
  when 'gold_master'
@@ -63,7 +63,7 @@ module Leeroy
63
63
  when 'application'
64
64
  getGoldMasterImageIndex.to_i
65
65
  else
66
- raise "unable to determine image index for phase '#{phase.to_s}'"
66
+ raise "unable to determine image index for phase '#{phase}'"
67
67
  end
68
68
  end
69
69
 
@@ -7,11 +7,20 @@ module Leeroy
7
7
 
8
8
  def renderTemplate(template, b = binding)
9
9
  begin
10
- logger.debug "processing template '#{template}'"
10
+ # is the template a file?
11
+ begin
12
+ template_str = File.read(template)
13
+ logger.debug "reading template from '#{template}'"
14
+
15
+ rescue SystemCallError => e
16
+ logger.debug e.message
17
+ template_str = template
18
+ logger.debug "reading template from provided string"
19
+ end
11
20
 
12
21
  # run the ERB renderer in a separate thread, restricted
13
22
  # http://www.stuartellis.eu/articles/erb/
14
- ERB.new(File.read(template), 0).result(binding)
23
+ ERB.new(template_str, 0).result(b)
15
24
 
16
25
  rescue StandardError => e
17
26
  raise e
@@ -0,0 +1,85 @@
1
+ require 'leeroy'
2
+ require 'leeroy/task'
3
+ require 'leeroy/types/fixture'
4
+ require 'leeroy/helpers/aws'
5
+ require 'leeroy/helpers/template'
6
+
7
+ module Leeroy
8
+ module Task
9
+ class Fixture < Leeroy::Task::Base
10
+ include Leeroy::Helpers::AWS
11
+ include Leeroy::Helpers::Template
12
+
13
+ def perform(args = self.args, options = self.options, global_options = self.global_options)
14
+ begin
15
+ super(args, options, global_options)
16
+
17
+ state = self.state
18
+
19
+ # what kind of fixture are we processing?
20
+ fixture = Leeroy::Types::Fixture.from_s(options[:fixture])
21
+
22
+ logger.debug "processing a '#{fixture}' fixture"
23
+
24
+ # process it
25
+ processed = self.send(fixture.value.to_sym, state, options)
26
+
27
+ logger.debug "processed: #{processed.inspect}"
28
+
29
+ dump_state
30
+
31
+ logger.debug "done performing for #{self.class}"
32
+
33
+ rescue StandardError => e
34
+ raise e
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def postgres(state, options)
41
+ begin
42
+ # extract params from options
43
+ header = options[:header]
44
+
45
+ # get the DB template from S3
46
+ dumpsrc = buildS3ObjectName(checkEnv('LEEROY_DB_TEMPLATE'), 'sql')
47
+
48
+ logger.debug "retrieving DB template from '#{dumpsrc}'"
49
+
50
+ dumpobj = genSemaphore(dumpsrc)
51
+
52
+ # is the template in S3?
53
+ raise "DB template not available in S3" unless checkSemaphore(dumpobj)
54
+
55
+ # start building the DB dump
56
+ dump = ''
57
+ dumptemplate = getSemaphore(dumpobj)
58
+
59
+ unless header.nil?
60
+ # render the DB header
61
+ headertemplate = File.join(checkEnv('LEEROY_PROVISIONING_TEMPLATE_PREFIX'), header)
62
+ logger.debug "rendering header template '#{headertemplate}'"
63
+ dump.concat(renderTemplate(headertemplate))
64
+ end
65
+
66
+ # render the DB template
67
+ dump.concat(renderTemplate(dumptemplate))
68
+
69
+ # store the rendered template in S3
70
+ dumpdst = buildS3ObjectName(checkEnv('LEEROY_DB_NAME') + '.sql', 'sql')
71
+
72
+ logger.debug "storing DB template in '#{dumpdst}'"
73
+
74
+ dumpobj = genSemaphore(dumpdst, dump)
75
+
76
+ setSemaphore(dumpobj)
77
+
78
+ rescue StandardError => e
79
+ raise e
80
+ end
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -17,7 +17,8 @@ module Leeroy
17
17
  begin
18
18
  super(args, options, global_options)
19
19
 
20
- phase = Leeroy::Types::Phase.new(self.state.fetch('phase', options[:phase]))
20
+ phase = Leeroy::Types::Phase.resolve(self.state.fetch('phase'), options[:phase])
21
+ logger.debug "phase: #{phase}"
21
22
  self.state.phase = phase
22
23
 
23
24
  # create image
@@ -17,7 +17,8 @@ module Leeroy
17
17
  begin
18
18
  super(args, options, global_options)
19
19
 
20
- phase = Leeroy::Types::Phase.new(self.state.fetch('phase', options[:phase]))
20
+ phase = Leeroy::Types::Phase.resolve(self.state.fetch('phase'), options[:phase])
21
+ logger.debug "phase: #{phase}"
21
22
  self.state.phase = phase
22
23
 
23
24
  # resolve various AWS resources from human-readable inputs
@@ -0,0 +1,70 @@
1
+ require 'typesafe_enum'
2
+
3
+ require 'leeroy/helpers/logging'
4
+
5
+ module Leeroy
6
+ module Types
7
+ ##
8
+ # Implements the [Typesafe Enum
9
+ # pattern](http://www.oracle.com/technetwork/java/page1-139488.html#replaceenums).
10
+ # Implement your own classes that inherit from this.
11
+ #
12
+ # Valid values for these enums must be Strings or otherwise stringifiable.
13
+ #
14
+ # Usage:
15
+ # ```
16
+ # class EnumClass < Leeroy::Types::Enum
17
+ # # 'foo' and 'bar' are the only acceptable values for EnumClass
18
+ # new :FOO
19
+ # new :BAR
20
+ # end
21
+ #
22
+ # enum_valid = Leeroy::Types::EnumClass.resolve('foo')
23
+ # # returns a valid instance of Leeroy::Types::EnumClass::FOO
24
+ # enum_valid.to_s
25
+ # # returns 'foo'
26
+ # enum_invalid = Leeroy::Types::EnumClass.resolve('baz')
27
+ # # raises an exception
28
+ # ```
29
+ #
30
+ class Enum < TypesafeEnum::Base
31
+
32
+ def to_s
33
+ self.value
34
+ end
35
+
36
+ ##
37
+ # Given a string or something that can be stringified, returns a subclass
38
+ # of the parent enum with a value matching the provided string.
39
+ #
40
+ # Accepts an optional second argument; if the first argument cannot be
41
+ # resolved by the enum, the second argument will be resolved.
42
+ #
43
+ def self.resolve(candidate, alternate = nil)
44
+ resolved = candidate.kind_of?(Leeroy::Types::Enum) ? candidate : self.from_s(candidate)
45
+
46
+ if candidate.nil?
47
+ resolved = self.resolve(alternate, nil) unless alternate.nil?
48
+ end
49
+
50
+ # FIXME raise some more appropriate type of error
51
+ raise "invalid value for enum" if resolved.nil?
52
+
53
+ resolved
54
+ end
55
+
56
+ def resolve(candidate, alternate = nil)
57
+ self.resolve(candidate, alternate)
58
+ end
59
+
60
+ def self.from_s(x)
61
+ self.find_by_value_str(x.to_s)
62
+ end
63
+
64
+ def from_s(x)
65
+ self.from_s(x)
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,13 @@
1
+ require 'leeroy/types/enum'
2
+
3
+ module Leeroy
4
+ module Types
5
+ class Fixture < Leeroy::Types::Enum
6
+
7
+ new :POSTGRES
8
+ new :CLOUDANT, 'FIXME Cloudant not implemented yet'
9
+ new :S3, 'FIXME S3 not implemented yet'
10
+
11
+ end
12
+ end
13
+ end
@@ -11,7 +11,7 @@ module Leeroy
11
11
  include Leeroy::Helpers::Dumpable
12
12
  include Leeroy::Helpers::Logging
13
13
 
14
- property :phase, required: true, coerce: Leeroy::Types::Phase
14
+ property :phase, required: true, coerce: lambda {|x| Leeroy::Types::Phase.from_s(x.to_s)}
15
15
  property :aws_params
16
16
 
17
17
  # AWS-specific params
@@ -13,7 +13,7 @@ module Leeroy
13
13
  include Leeroy::Helpers::Dumpable
14
14
  include Leeroy::Helpers::Logging
15
15
 
16
- property :phase, required: true, coerce: Leeroy::Types::Phase
16
+ property :phase, required: true, coerce: lambda {|x| Leeroy::Types::Phase.from_s(x.to_s)}
17
17
  property :aws_params
18
18
 
19
19
  # AWS-specific params
@@ -1,26 +1,11 @@
1
- require 'leeroy/helpers/logging'
1
+ require 'leeroy/types/enum'
2
2
 
3
3
  module Leeroy
4
4
  module Types
5
- class Phase < String
6
- include Leeroy::Helpers::Logging
5
+ class Phase < Leeroy::Types::Enum
7
6
 
8
- VALID_PHASE = ['gold_master', 'application']
9
-
10
- def initialize(*args, &block)
11
- begin
12
- super
13
-
14
- phase = self.to_s
15
- raise "invalid value for phase: '#{phase}'" unless VALID_PHASE.include?(phase)
16
-
17
- rescue TypeError => e
18
- raise "invalid value for phase: #{e.message}"
19
-
20
- rescue StandardError => e
21
- raise e
22
- end
23
- end
7
+ new :GOLD_MASTER
8
+ new :APPLICATION
24
9
 
25
10
  end
26
11
  end
@@ -17,7 +17,7 @@ module Leeroy
17
17
  property :app_name, coerce: String
18
18
  property :instanceid, coerce: String
19
19
  property :imageid, coerce: String
20
- property :phase, coerce: Leeroy::Types::Phase
20
+ property :phase, coerce: lambda {|x| Leeroy::Types::Phase.from_s(x.to_s)}
21
21
  property :semaphore, coerce: Leeroy::Types::Semaphore
22
22
  property :sgid, coerce: String
23
23
  property :subnetid, coerce: String
@@ -1,3 +1,3 @@
1
1
  module Leeroy
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leeroy_app
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Huff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-15 00:00:00.000000000 Z
11
+ date: 2016-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aruba
@@ -220,6 +220,20 @@ dependencies:
220
220
  - - ~>
221
221
  - !ruby/object:Gem::Version
222
222
  version: '1.0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: typesafe_enum
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ~>
228
+ - !ruby/object:Gem::Version
229
+ version: '0.1'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ~>
235
+ - !ruby/object:Gem::Version
236
+ version: '0.1'
223
237
  - !ruby/object:Gem::Dependency
224
238
  name: yell
225
239
  requirement: !ruby/object:Gem::Requirement
@@ -260,6 +274,7 @@ extra_rdoc_files: []
260
274
  files:
261
275
  - .codeclimate.yml
262
276
  - .gitignore
277
+ - .rdoc_options
263
278
  - .rspec
264
279
  - .rubocop.yml
265
280
  - .ruby-version
@@ -286,12 +301,15 @@ files:
286
301
  - lib/leeroy/state.rb
287
302
  - lib/leeroy/task.rb
288
303
  - lib/leeroy/task/base.rb
304
+ - lib/leeroy/task/fixture.rb
289
305
  - lib/leeroy/task/image.rb
290
306
  - lib/leeroy/task/instantiate.rb
291
307
  - lib/leeroy/task/sleep.rb
292
308
  - lib/leeroy/task/stub.rb
293
309
  - lib/leeroy/task/terminate.rb
294
310
  - lib/leeroy/types/dash.rb
311
+ - lib/leeroy/types/enum.rb
312
+ - lib/leeroy/types/fixture.rb
295
313
  - lib/leeroy/types/image.rb
296
314
  - lib/leeroy/types/instance.rb
297
315
  - lib/leeroy/types/mash.rb