Class: Stacco::Stack

Inherits:
Object
  • Object
show all
Defined in:
lib/stacco.rb

Instance Method Summary collapse

Constructor Details

#initialize(config_object) ⇒ Stack

Returns a new instance of Stack.



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/stacco.rb', line 185

def initialize(config_object)
  @config_object = config_object

  aws_creds = self.aws_credentials

  @services = {
    ec2: AWS::EC2.new(aws_creds),
    s3: AWS::S3.new(aws_creds),
    cloudformation: AWS::CloudFormation.new(aws_creds),
    cloudfront: AWS::CloudFront.new(aws_creds)
  }

  @aws_stack = @services[:cloudformation].stacks[self.name]
  @aws_stack.service_registry = @services
end

Instance Method Details

#aws_credentialsObject



238
239
240
# File 'lib/stacco.rb', line 238

def aws_credentials
  Hash[ *(self.config['aws'].map{ |k, v| [k.intern, v] }.flatten) ]
end

#aws_statusObject



218
219
220
# File 'lib/stacco.rb', line 218

def aws_status
  @aws_stack.status
end

#cloudformation_templateObject



291
292
293
294
# File 'lib/stacco.rb', line 291

def cloudformation_template
  tpl = Stacco::Template.new(self, Stacco::Resources::Templates[:cloudformation])
  tpl.result(self.config)
end

#configObject



226
227
228
# File 'lib/stacco.rb', line 226

def config
  YAML.load(@config_object.read)
end

#config=(new_config) ⇒ Object



230
231
232
# File 'lib/stacco.rb', line 230

def config=(new_config)
  @config_object.write(new_config.to_yaml)
end

#connectionsObject



201
202
203
204
205
# File 'lib/stacco.rb', line 201

def connections
  connections = {}
  @aws_stack.elastic_ips.each{ |eip| connections[eip.instance.tags["aws:cloudformation:logical-id"]] = eip }
  connections
end

#descriptionObject



242
243
244
# File 'lib/stacco.rb', line 242

def description
  self.config['description']
end

#down!Object



280
281
282
283
284
285
286
287
288
289
# File 'lib/stacco.rb', line 280

def down!
  return false unless self.up?

  @aws_stack.buckets.each{ |bucket| bucket.delete! }
  @aws_stack.delete

  Kernel.sleep(2) while self.up?

  true
end

#iam_keypair_nameObject



300
301
302
# File 'lib/stacco.rb', line 300

def iam_keypair_name
  "stacco-" + self.iam_private_key.key.split('/').last
end

#iam_private_keyObject



296
297
298
# File 'lib/stacco.rb', line 296

def iam_private_key
  @config_object.bucket.objects.with_prefix("sshkey/#{self.name}-").to_a.sort_by{ |obj| obj.key.split('/').last.split('-').last.to_i }.last
end

#iam_private_key_materialObject



304
305
306
# File 'lib/stacco.rb', line 304

def iam_private_key_material
  self.iam_private_key.read
end

#initialize_distributions!Object



270
271
272
273
274
275
276
277
278
# File 'lib/stacco.rb', line 270

def initialize_distributions!
  cloudfront_certs = self.config['cloudfront']['certificates']
  @services[:cloudfront].distributions.each do |dist|
    dist.update do
      dist.price_class = :"100"
      dist.certificate = cloudfront_certs[dist.aliases.first]
    end
  end
end

#must_be_up!Object



211
212
213
214
215
216
# File 'lib/stacco.rb', line 211

def must_be_up!
  unless self.up?
    $stderr.puts "stack #{self.name} is down"
    Kernel.exit 1
  end
end

#nameObject



246
247
248
# File 'lib/stacco.rb', line 246

def name
  self.config['name']
end

#name=(new_name) ⇒ Object



250
251
252
# File 'lib/stacco.rb', line 250

def name=(new_name)
  update_config{ |config| config.merge("name" => new_name) }
end

#resource_summariesObject



207
208
209
# File 'lib/stacco.rb', line 207

def resource_summaries
  @aws_stack.resource_summaries
end

#statusObject



222
223
224
# File 'lib/stacco.rb', line 222

def status
  self.up? ? self.aws_status : "DOWN"
end

#stream_eventsObject



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/stacco.rb', line 308

def stream_events
  Enumerator.new do |out|
    known_events = Set.new
    ticks_without_add = 0

    while self.up?
      added = 0

      @aws_stack.events.sort_by{ |ev| ev.timestamp }.each do |event|
        next if known_events.include? event.event_id
        out.yield event

        known_events.add event.event_id
        added += 1
        ticks_without_add = 0

      end

      ticks_without_add += 1 if added == 0

      if ticks_without_add >= 8 and (Math.log2(ticks_without_add) % 1) == 0.0
        jobs = @aws_stack.resource_summaries
        active_jobs = jobs.find_all{ |job| job[:resource_status] =~ /IN_PROGRESS$/ }.map{ |job| job[:logical_resource_id] }.sort
        unless active_jobs.empty?
          out.yield OpenStruct.new(
            logical_resource_id: "Scheduler",
            status: "WAIT",
            operation: "WAIT",
            timestamp: Time.now,
            error: "waiting on #{active_jobs.join(', ')}"
          )
        end
      end

      Kernel.sleep 2
    end
  end
end

#up!Object



258
259
260
261
262
263
264
# File 'lib/stacco.rb', line 258

def up!
  if @aws_stack.exists?
    @aws_stack.update(template: self.cloudformation_template)
  else
    @services[:cloudformation].stacks.create(self.name, self.cloudformation_template)
  end
end

#up?Boolean

Returns:

  • (Boolean)


254
255
256
# File 'lib/stacco.rb', line 254

def up?
  @aws_stack.exists?
end

#up_sinceObject



266
267
268
# File 'lib/stacco.rb', line 266

def up_since
  @aws_stack.creation_time if @aws_stack.exists?
end

#update_configObject



234
235
236
# File 'lib/stacco.rb', line 234

def update_config
  # TODO
end