Class: Middleman::Cli::CloudFront::Invalidate

Inherits:
Thor::Group
  • Object
show all
Includes:
Thor::Actions
Defined in:
lib/middleman-cloudfront/commands/invalidate.rb

Overview

This class provides an “invalidate” command for the middleman CLI.

Constant Summary collapse

INVALIDATION_LIMIT =
1000
INDEX_REGEX =
/
  \A
    (.*\/)?
    index\.html
  \z
/ix

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/middleman-cloudfront/commands/invalidate.rb', line 23

def self.exit_on_failure?
  true
end

Instance Method Details

#invalidate(options = nil, files = nil) ⇒ Object

Raises:

  • (StandardError)


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/middleman-cloudfront/commands/invalidate.rb', line 27

def invalidate(options = nil, files = nil)

  # If called via commandline, discover config (from bin/middleman)
  if options.nil?
    app = Middleman::Application.new do
      config[:mode] = :config
      config[:exit_before_ready] = true
      config[:watcher_disable] = true
      config[:disable_sitemap] = true
    end

    # Get the options from the cloudfront extension
    extension = app.extensions[:cloudfront]
    unless extension.nil?
      options = extension.options
    end
  end

  if options.nil?
    configuration_usage
  end

  [:distribution_id, :filter].each do |key|
    raise StandardError, "Configuration key #{key} is missing." if options.public_send(key).nil?
  end

  puts '## Invalidating files on CloudFront'

  fog_options = {
    :provider => 'AWS'
  }

  fog_options.merge!(
    if options.access_key_id && options.secret_access_key
      {
        :aws_access_key_id     => options.access_key_id,
        :aws_secret_access_key => options.secret_access_key
      }
    else
      { :use_iam_profile => true }
    end
  )

  cdn = Fog::CDN.new(fog_options)

  distribution = cdn.distributions.get(options.distribution_id)

  raise StandardError, "Cannot access Distribution with id #{options.distribution_id}." if distribution.nil?


  # CloudFront limits the amount of files which can be invalidated by one request to 1000.
  # If there are more than 1000 files to invalidate, do so sequentially and wait until each validation is ready.
  # If there are max 1000 files, create the invalidation and return immediately.
  files = normalize_files(files || list_files(options.filter))
  return if files.empty?

  if files.count <= INVALIDATION_LIMIT
    puts "Invalidating #{files.count} files. It might take 10 to 15 minutes until all files are invalidated."
    puts 'Please check the AWS Management Console to see the status of the invalidation.'
    invalidation = distribution.invalidations.create(:paths => files)
    raise StandardError, %(Invalidation status is #{invalidation.status}. Expected "InProgress") unless invalidation.status == 'InProgress'
  else
    slices = files.each_slice(INVALIDATION_LIMIT)
    puts "Invalidating #{files.count} files in #{slices.count} batch(es). It might take 10 to 15 minutes per batch until all files are invalidated."
    slices.each_with_index do |slice, i|
      puts "Invalidating batch #{i + 1}..."
      invalidation = distribution.invalidations.create(:paths => slice)
      invalidation.wait_for { ready? } unless i == slices.count - 1
    end
  end
end