├── .gitignore ├── CHANGELOG.md ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── Rakefile ├── bin └── ipecache ├── ipecache.gemspec ├── lib ├── ipecache.rb └── ipecache │ ├── plugins.rb │ ├── plugins │ ├── akamai.rb │ ├── ats_chef.rb │ ├── cloudflare.rb │ ├── cloudfront.rb │ ├── edgecast.rb │ ├── fastly.rb │ ├── local.rb │ ├── maxcdn.rb │ ├── plugin.rb │ ├── swisstxt_cdn.rb │ └── varnish.rb │ └── runner.rb └── plugins ├── ATSChef.md ├── Akamai.md ├── CloudFlare.md ├── Cloudfront.md ├── Edgecast.md ├── Fastly.md ├── Local.md ├── MaxCDN.md ├── README.md ├── SWISS_TXT_CDN.md └── Varnish.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .idea/ 3 | .bundle 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.16 (Sept 6th, 2019) 2 | 3 | Bugfixes: 4 | 5 | - Update to add missing runtime_dependency from 0.0.15 6 | 7 | 8 | ## 0.0.15 (Sept 5th, 2019) 9 | 10 | Bugfixes: 11 | 12 | - Update Akamai API to v3 (Thanks to @dolvany https://github.com/jonlives/ipecache/pull/17) 13 | 14 | ## 0.0.14 (May 17th, 2017) 15 | 16 | Bugfixes: 17 | 18 | - Fix hef attribute naming in ATS plugin (Thanks to @lozzd https://github.com/jonlives/ipecache/pull/16) 19 | 20 | ## 0.0.13 (May 11th, 2017) 21 | 22 | Features: 23 | 24 | - Stop using deprecated Chef::REST, switch to ServerAPI (Thanks to @lozzd https://github.com/jonlives/ipecache/pull/15) 25 | 26 | ## 0.0.12 (April 20th, 2016) 27 | 28 | Features: 29 | 30 | - Varnish plugin (Thanks to @luisdavim https://github.com/jonlives/ipecache/pull/14) 31 | 32 | ## 0.0.11 (September 3rd, 2015) 33 | 34 | Bugfixes: 35 | 36 | - Added MaxCDN support (Thanks to @jmervine https://github.com/jonlives/ipecache/pull/13) 37 | 38 | 39 | ## 0.0.10 (January 8th, 2015) 40 | 41 | Bugfixes: 42 | 43 | - Fix Fastly plugin to work without SSLv3, due to it being deprecated as a result of the POODLE vulnerability (Re-fixing https://github.com/jonlives/ipecache/issues/10) 44 | 45 | 46 | ## 0.0.9 (December 16th, 2014) 47 | 48 | Features: 49 | 50 | - Cloudfront plugin (Thanks to https://github.com/danieleva) 51 | 52 | ## 0.0.8 (August 14th, 2014) 53 | 54 | Features: 55 | 56 | - Fix to Fastly plugin for https://github.com/jonlives/ipecache/issues/10 57 | 58 | ## 0.0.7 (August 14th, 2014) 59 | 60 | Features: 61 | 62 | - Local plugin (Thanks to https://github.com/jmara) 63 | - SWISSTXT plugin (Thanks to https://github.com/niwo) 64 | 65 | ## 0.0.6 (April 28, 2014) 66 | 67 | Features: 68 | 69 | - Cloudflare plugin (Thanks to https://github.com/adedommelin) 70 | - Add quiet mode (Thanks to https://github.com/nespresso) 71 | - Add -n short option to --nofail (Thanks to https://github.com/nespresso) 72 | 73 | Bugfixes: 74 | 75 | - Fix plugin_puts_error to print URL (Thanks to https://github.com/nespresso) 76 | 77 | ## 0.0.5 (April 25, 2014) 78 | 79 | Features: 80 | 81 | - Switched Akamai plugin to use new CCUAPI (Thanks to https://github.com/nespresso) 82 | 83 | ## 0.0.1 (March 20, 2013) 84 | 85 | Features: 86 | 87 | - Initial version. 88 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | ipecache (0.0.11) 5 | app_conf (>= 0.4.0) 6 | aws-sdk-v1 (>= 1.0) 7 | choice (>= 0.1.6) 8 | faraday_middleware (>= 0.9.0) 9 | maxcdn (>= 0.2.1) 10 | public_suffix (>= 1.4.2) 11 | 12 | GEM 13 | remote: https://rubygems.org/ 14 | specs: 15 | addressable (2.3.8) 16 | app_conf (0.4.2) 17 | aws-sdk-v1 (1.65.0) 18 | json (~> 1.4) 19 | nokogiri (>= 1.4.4) 20 | choice (0.2.0) 21 | curb (0.8.8) 22 | curb-fu (0.6.2) 23 | curb (>= 0.5.4.0) 24 | rack-test (>= 0.2.0) 25 | faraday (0.9.1) 26 | multipart-post (>= 1.2, < 3) 27 | faraday_middleware (0.10.0) 28 | faraday (>= 0.7.4, < 0.10) 29 | json (1.8.3) 30 | jwt (1.5.1) 31 | maxcdn (0.2.1) 32 | curb-fu (~> 0.6.2) 33 | signet (~> 0.5.1) 34 | mini_portile (0.6.2) 35 | multi_json (1.11.2) 36 | multipart-post (2.0.0) 37 | nokogiri (1.6.6.2) 38 | mini_portile (~> 0.6.0) 39 | public_suffix (1.5.1) 40 | rack (1.6.4) 41 | rack-test (0.6.3) 42 | rack (>= 1.0) 43 | signet (0.5.1) 44 | addressable (>= 2.2.3) 45 | faraday (>= 0.9.0.rc5) 46 | jwt (>= 0.1.5) 47 | multi_json (>= 1.0.0) 48 | 49 | PLATFORMS 50 | ruby 51 | 52 | DEPENDENCIES 53 | ipecache! 54 | 55 | BUNDLED WITH 56 | 1.10.6 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Ipecache 2 | ---------- 3 | Author:: Jon Cowie () 4 | Copyright:: Copyright (c) 2013 Jon Cowie 5 | License:: GPL 6 | 7 | Plugin API 8 | ---------- 9 | Modified version of code added to knife-spork under the following license: 10 | 11 | Author:: Seth Vargo () 12 | Copyright:: Copyright (c) 2012 Seth Vargo 13 | License:: GPL -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ipecache 2 | =========== 3 | Ipecache is an extensible tool for purging URLs from Caches and CDNs. 4 | 5 | Installation 6 | ------------ 7 | ### Gem Install (recommended) 8 | `ipecache` is available on rubygems. Add the following to your `Gemfile`: 9 | 10 | ```ruby 11 | gem 'ipecache' 12 | ``` 13 | 14 | or install the gem manually: 15 | 16 | ```bash 17 | gem install ipecache 18 | ``` 19 | 20 | Ipecache Configuration 21 | ------------------- 22 | Ipecache will not work with no configuration, so before you can purge anything, you'll need to specify some configuration for the plugins you wish to use. 23 | 24 | Ipecache will look for a configuration file in the following locations, in ascending order of precedence: 25 | 26 | - `/etc/ipecache-config.yml` 27 | - `~/.ipecache/ipecache-config.yml` 28 | 29 | Anything set in the configuration file in your home directory for example, will override options set in `/etc`. 30 | 31 | Below is a sample config file with all supported options and all shipped plugins enabled below, followed by an explanation of each section. 32 | 33 | Please note, if you do not want to use a particular plugin, don't specify any configuration for it and it will automatically be disabled. 34 | 35 | ```yaml 36 | plugins: 37 | atschef: 38 | knife_config: /my/.chef/knife.rb 39 | chef_role: ATSRole 40 | fastly: 41 | api_key: abc123abc123abc123abc123abc123abc123 42 | edgecast: 43 | account_id: 1A2B 44 | api_key: abc123 45 | maxcdn: 46 | alias: myalias 47 | token: 1A2B 48 | secret: abc123 49 | zone: 1234 50 | akamai: 51 | client_secret: xxxxxxx 52 | host: xxxxxxx 53 | access_token: xxxxxxx 54 | client_token: xxxxxxx 55 | cloudflare: 56 | login: foo@bar.com 57 | api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 58 | local: 59 | hosts: 60 | - cache1.mydomain.com 61 | - cache2.mydomain.com 62 | use_ssh: false 63 | swisstxt_cdn: 64 | api_key: sample_key_e8e55aff-61e3-4588-ab98-4d3ea58be7c8 65 | api_secret: xyz5678xyz5678xyz5678xyz5678xyz5678xyz5678xyz5678 66 | cloudfront: 67 | access_key_id: yyyyyyyyyyyyyyyy 68 | secret_access_key: xxxxxxxxxxxxxxxxxx 69 | region: eu-west-1 70 | batch_size: 3000 71 | distributions: 72 | - distribution1 73 | - distribution2 74 | ``` 75 | 76 | #### atschef 77 | For more information on how to configure the ATS/Chef plugin, please read the [plugins/ATSChef.md](plugins/ATSChef.md) file. 78 | 79 | #### Fastly 80 | For more information on how to configure the Fastly CDN plugin, please read the [plugins/Fastly.md](plugins/Fastly.md) file. 81 | 82 | #### Edgecast 83 | For more information on how to configure the Edgecast CDN plugin, please read the [plugins/Edgecast.md](plugins/Edgecast.md) file. 84 | 85 | #### Akamai 86 | For more information on how to configure the Akamai plugin, please read the [plugins/Akamai.md](plugins/Akamai.md) file. 87 | 88 | #### CloudFlare 89 | For more information on how to configure the CloudFlare plugin, please read the [plugins/CloudFlare.md](plugins/CloudFlare.md) file. 90 | 91 | #### Local 92 | For more information on how to configure the Local plugin, please read the [plugins/Local.md](plugins/Local.md) file. 93 | 94 | #### SWISS TXT CDN 95 | For more information on how to configure the SWISS TXT CDN plugin, please read the [plugins/SWISS_TXT_CDN.md](plugins/SWISS_TXT_CDN.md) file. 96 | 97 | #### Amazon Cloudfront 98 | For more information on how to configure the Amazon Cloudfront CDN plugin, please read the [plugins/Cloudfront.md](plugins/Cloudfront.md) file. 99 | 100 | #### MaxCDN 101 | For more information on how to configure the MaxCDN plugin, please read the [plugins/MaxCDN.md](plugins/MaxCDN.md) file. 102 | 103 | Ipecache Usage 104 | ----------- 105 | The main component of Ipecache, and the program which initialises and calls all plugins is called `ipecache`. 106 | 107 | #### Usage 108 | ```bash 109 | ipecache [-f -u -c -p -l -q --status] 110 | ``` 111 | 112 | * Mandatory Parameters (you must specify one or the other) 113 | * -f: Specifies a file containg a newline seperated list of URLS to purge 114 | * -u: Specifies a single URL to purge 115 | 116 | * Optional Parameters: 117 | * --status: Prints the status of all ipecache plugins 118 | * -c: Indicates that only CDN plugins should be run 119 | * -p: Indicates that only local proxy plugins should be run. 120 | * -l: Specify a file to log errors to 121 | * -n, --nofail: Do not quit on error, continue purging 122 | * -q, --quiet: Suppress all console output 123 | 124 | 125 | #### Example (Checking plugin status) 126 | 127 | ```text 128 | $> ipecache --status 129 | Ipecache Status: 130 | 131 | Ipecache::Plugins::Akamai: enabled 132 | Ipecache::Plugins::ATSChef: enabled 133 | Ipecache::Plugins::Edgecast: enabled 134 | Ipecache::Plugins::Fastly: enabled 135 | Ipecache::Plugins::Local: enabled 136 | ``` 137 | 138 | #### Example (Purging a single URL from local proxies only) 139 | 140 | ```text 141 | $> ipecache -u https://img3.etsystatic.com/000/0/5241384/il_340x270.220445599.jpg -p 142 | 143 | Running plugins registered for Proxy Purge... 144 | 145 | 146 | Ipecache::Plugins::ATSChef: Beginning URL Purge from ATS... 147 | Ipecache::Plugins::ATSChef: Finding ATS Servers... 148 | Ipecache::Plugins::ATSChef: Purging https://img.mydomain.com/image9.jpg 149 | Ipecache::Plugins::ATSChef: --Purge from cache1.mydomain.com not needed, asset not found 150 | Ipecache::Plugins::ATSChef: --Purged from cache2.mydomain.com sucessfully 151 | 152 | All done! 153 | ``` 154 | 155 | #### Example (Purging a file containing 2 URLs from CDNS only) 156 | 157 | ```text 158 | $> ipecache -f ~/urlfile -c 159 | 160 | Running plugins registered for CDN Purge... 161 | 162 | 163 | Ipecache::Plugins::Akamai: Beginning URL Purge from Akamai... 164 | Ipecache::Plugins::Akamai: Purging https://img.mydomain.com/image9.jpg 165 | Ipecache::Plugins::Akamai: Purge successful! 166 | Ipecache::Plugins::Akamai: Purging https://img.mydomain.com/image10.jpg 167 | Ipecache::Plugins::Akamai: Purge successful! 168 | 169 | Ipecache::Plugins::Edgecast: Beginning URL Purge from Edgecast... 170 | Ipecache::Plugins::Edgecast: Purging https://img.mydomain.com/image9.jpg 171 | Ipecache::Plugins::Edgecast: Purge successful! 172 | Ipecache::Plugins::Edgecast: Purging https://img.mydomain.com/image10.jpg 173 | Ipecache::Plugins::Edgecast: Purge successful! 174 | 175 | Ipecache::Plugins::Fastly: Beginning URL Purge from Fastly... 176 | Ipecache::Plugins::Fastly: Purging https://img.mydomain.com/image9.jpg 177 | Ipecache::Plugins::Fastly: Purge successful! 178 | Ipecache::Plugins::Fastly: Purging https://img.mydomain.com/imag10.jpg 179 | Ipecache::Plugins::Fastly: Purge successful! 180 | 181 | All done! 182 | ``` 183 | 184 | #### Example (Purging a file containing 2 URLs from proxies and CDNS) 185 | 186 | ```text 187 | $> ipecache -f ~/urlfile 188 | 189 | Running plugins registered for Proxy Purge... 190 | 191 | 192 | Ipecache::Plugins::ATSChef: Beginning URL Purge from ATS... 193 | Ipecache::Plugins::ATSChef: Finding ATS Servers... 194 | Ipecache::Plugins::ATSChef: Purging https://img.mydomain.com/image9.jpg 195 | Ipecache::Plugins::ATSChef: --Purge from cache1.mydomain.com not needed, asset not found 196 | Ipecache::Plugins::ATSChef: --Purged from cache2.mydomain.com sucessfully 197 | Ipecache::Plugins::ATSChef: Purging https://img.mydomain.com/image10.jpg 198 | Ipecache::Plugins::ATSChef: --Purge from cache1.mydomain.com not needed, asset not found 199 | Ipecache::Plugins::ATSChef: --Purged from cache2.mydomain.com sucessfully 200 | 201 | Running plugins registered for CDN Purge... 202 | 203 | 204 | Ipecache::Plugins::Akamai: Beginning URL Purge from Akamai... 205 | Ipecache::Plugins::Akamai: Purging https://img.mydomain.com/image9.jpg 206 | Ipecache::Plugins::Akamai: Purge successful! 207 | Ipecache::Plugins::Akamai: Purging https://img.mydomain.com/image10.jpg 208 | Ipecache::Plugins::Akamai: Purge successful! 209 | 210 | Ipecache::Plugins::Edgecast: Beginning URL Purge from Edgecast... 211 | Ipecache::Plugins::Edgecast: Purging https://img.mydomain.com/image9.jpg 212 | Ipecache::Plugins::Edgecast: Purge successful! 213 | Ipecache::Plugins::Edgecast: Purging https://img.mydomain.com/image10.jpg 214 | Ipecache::Plugins::Edgecast: Purge successful! 215 | 216 | Ipecache::Plugins::Fastly: Beginning URL Purge from Fastly... 217 | Ipecache::Plugins::Fastly: Purging https://img.mydomain.com/image9.jpg 218 | Ipecache::Plugins::Fastly: Purge successful! 219 | Ipecache::Plugins::Fastly: Purging https://img.mydomain.com/imag10.jpg 220 | Ipecache::Plugins::Fastly: Purge successful! 221 | 222 | All done! 223 | ``` 224 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require 'bundler/gem_tasks' 3 | -------------------------------------------------------------------------------- /bin/ipecache: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # ipecache - Extensible tool for purging URLs from Caches and CDNs. 4 | # 5 | # Author:: Jon Cowie () 6 | 7 | require 'choice' 8 | require 'ipecache/runner' 9 | include Ipecache::Runner 10 | 11 | Choice.options do 12 | header "" 13 | header "Specific options:" 14 | 15 | option :status, :required => false do 16 | long '--status' 17 | desc 'Show ipecache status information' 18 | end 19 | 20 | option :urlfile, :required => false do 21 | short '-f' 22 | long '--file=PATH_TO_URL_FILE' 23 | desc 'File containing urls to purge from caches' 24 | end 25 | 26 | option :url, :required => false do 27 | short '-u' 28 | long '--url=URL_TO_PURGE' 29 | desc 'URL to be purged from caches' 30 | end 31 | 32 | option :proxyonly, :required => false do 33 | short '-p' 34 | long '--proxy-only' 35 | desc 'Only purge from proxies' 36 | end 37 | 38 | option :cdnonly, :required => false do 39 | short '-c' 40 | long '--cdn-only' 41 | desc 'Only purge from CDNs' 42 | end 43 | 44 | option :log_file, :required => false do 45 | short '-l' 46 | long '--log-file' 47 | desc 'Log errors to specified file in addition to stdout' 48 | end 49 | 50 | option :continue_on_error, :required => false do 51 | short '-n' 52 | long '--nofail' 53 | desc 'Continue on errors instead of exiting' 54 | end 55 | 56 | option :quiet_mode, :required => false do 57 | short '-q' 58 | long '--quiet' 59 | desc 'Suppress all console output' 60 | end 61 | end 62 | 63 | if Choice.choices[:quiet_mode] 64 | @quiet_mode = Choice.choices[:quiet_mode] 65 | end 66 | 67 | if Choice.choices[:status] 68 | puts "Ipecache Status:" 69 | puts "" 70 | Ipecache::Plugins.klasses.each do |klass| 71 | plugin = klass.new(:config => ipecache_config) 72 | puts "#{klass}: #{plugin.enabled? ? 'enabled' : 'disabled'}" 73 | end 74 | exit 0 75 | end 76 | 77 | if Choice.choices[:url] 78 | @urls = [Choice.choices[:url]] 79 | elsif Choice.choices[:urlfile] 80 | urlfile = Choice.choices[:urlfile] 81 | if File.exists?(urlfile) 82 | @urls = File.open(urlfile, 'r').readlines 83 | else 84 | if !@quiet_mode 85 | puts "Error: #{urlfile} doesn't exist." 86 | end 87 | exit 1 88 | end 89 | else 90 | Choice.help 91 | end 92 | 93 | if Choice.choices[:log_file] 94 | @log_file = Choice.choices[:log_file] 95 | end 96 | 97 | if Choice.choices[:continue_on_error] 98 | @continue_on_error = Choice.choices[:continue_on_error] 99 | end 100 | 101 | if !Choice.choices[:cdnonly] 102 | if !@quiet_mode 103 | puts "" 104 | puts "Running plugins registered for Proxy Purge..." 105 | puts "" 106 | end 107 | run_plugins(:proxy_purge) 108 | end 109 | 110 | if !Choice.choices[:proxyonly] 111 | if !@quiet_mode 112 | puts "" 113 | puts "Running plugins registered for CDN Purge..." 114 | puts "" 115 | end 116 | run_plugins(:cdn_purge) 117 | end 118 | 119 | if !@quiet_mode 120 | puts "" 121 | puts "All done!" 122 | end 123 | -------------------------------------------------------------------------------- /ipecache.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path('../lib', __FILE__) 2 | 3 | Gem::Specification.new do |gem| 4 | gem.name = 'ipecache' 5 | gem.version = '0.0.16' 6 | gem.authors = ["Jon Cowie"] 7 | gem.email = 'jonlives@gmail.com' 8 | gem.homepage = 'https://github.com/jonlives/ipecache' 9 | gem.summary = "An extensible tool for purging urls from caches and CDNs" 10 | gem.description = "An extensible tool for purging urls from caches and CDNs" 11 | 12 | gem.files = `git ls-files`.split($\) 13 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 14 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 15 | gem.name = "ipecache" 16 | gem.require_paths = ["lib"] 17 | 18 | gem.add_runtime_dependency 'app_conf', '>= 0.4.0' 19 | gem.add_runtime_dependency 'choice', '>= 0.1.6' 20 | gem.add_runtime_dependency 'faraday_middleware', '>= 0.9.0' 21 | gem.add_runtime_dependency 'public_suffix', '>= 1.4.2' 22 | gem.add_runtime_dependency 'aws-sdk-v1', '>= 1.0' 23 | gem.add_runtime_dependency 'maxcdn', '>= 0.2.1' 24 | gem.add_runtime_dependency 'akamai-edgegrid', '>= 1.0.7' 25 | end 26 | -------------------------------------------------------------------------------- /lib/ipecache.rb: -------------------------------------------------------------------------------- 1 | module Ipecache 2 | require 'ipecache/plugins' 3 | end 4 | -------------------------------------------------------------------------------- /lib/ipecache/plugins.rb: -------------------------------------------------------------------------------- 1 | module Ipecache 2 | module Plugins 3 | # Load each of the drop-in plugins 4 | Dir[File.expand_path('../plugins/**/*.rb', __FILE__)].each { |f| require f } 5 | 6 | def self.run(options = {}) 7 | hook = options[:hook].to_sym 8 | 9 | klasses.each do |klass| 10 | plugin = klass.new(options) 11 | plugin.send(hook) if plugin.respond_to?(hook) && plugin.enabled? 12 | end 13 | end 14 | 15 | # Get and return a list of all subclasses (plugins) that are not the base plugin 16 | def self.klasses 17 | @@klasses ||= self.constants.collect do |c| 18 | self.const_get(c) if self.const_get(c).is_a?(Class) && self.const_get(c) != Ipecache::Plugins::Plugin 19 | end.compact 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/akamai.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class AKAMAI < Plugin 6 | name :akamai 7 | hooks :cdn_purge 8 | 9 | def perform 10 | safe_require 'json' 11 | safe_require 'akamai/edgegrid' 12 | safe_require 'net/http' 13 | safe_require 'uri' 14 | 15 | client_secret = config.client_secret 16 | host = config.host 17 | access_token = config.access_token 18 | client_token = config.client_token 19 | 20 | if client_secret.nil? 21 | plugin_puts("Akamai client_secret not specified, Exiting...") 22 | exit 1 23 | end 24 | 25 | if host.nil? 26 | plugin_puts("Akamai host not specified, Exiting...") 27 | exit 1 28 | end 29 | 30 | if access_token.nil? 31 | plugin_puts("Akamai access_token not specified, Exiting...") 32 | exit 1 33 | end 34 | 35 | if client_token.nil? 36 | plugin_puts("Akamai client_token not specified, Exiting...") 37 | exit 1 38 | end 39 | 40 | plugin_puts "Beginning URL Purge from Akamai..." 41 | 42 | baseuri = URI("https://#{host}/") 43 | 44 | http = Akamai::Edgegrid::HTTP.new( 45 | address=baseuri.host, 46 | port=baseuri.port 47 | ) 48 | 49 | http.setup_edgegrid( 50 | :client_token => client_token, 51 | :client_secret => client_secret, 52 | :access_token => access_token, 53 | :max_body => 128 * 1024 54 | ) 55 | 56 | urls.each do |u| 57 | url = u.chomp 58 | plugin_puts ("Purging #{url}") 59 | 60 | post_request = Net::HTTP::Post.new( 61 | URI.join(baseuri.to_s, "/ccu/v3/delete/url/production").to_s, 62 | initheader = { 'Content-Type' => 'application/json' } 63 | ) 64 | 65 | post_request.body = { 66 | "objects" => ["#{url}"] 67 | }.to_json 68 | 69 | response = http.request(post_request) 70 | 71 | response_json = JSON.parse(response.body) 72 | response_httpStatus = response_json['httpStatus'] 73 | 74 | if response_httpStatus != 201 75 | plugin_puts_error(url,"Purge failed!") 76 | plugin_puts response.body 77 | exit 1 unless continue_on_error 78 | else 79 | plugin_puts "Purge successful!" 80 | end 81 | end 82 | end 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/ats_chef.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class ATSChef < Plugin 6 | name :atschef 7 | hooks :proxy_purge 8 | 9 | def perform 10 | safe_require 'chef' 11 | safe_require 'uri' 12 | 13 | knife_file = config.knife_config || "" 14 | chef_role = config.chef_role 15 | 16 | if knife_file.empty? 17 | plugin_puts "No knife config file specified. Exiting..." 18 | exit 1 19 | elsif File.exists?(knife_file) 20 | Chef::Config.from_file(knife_file) 21 | rest_api = Chef::ServerAPI.new(Chef::Config[:chef_server_url]) 22 | else 23 | plugin_puts "Knife config file #{knife_file} doesn't exist." 24 | exit 1 25 | end 26 | 27 | if !chef_role 28 | plugin_puts "Chef role not specified, Exiting..." 29 | exit 1 30 | end 31 | 32 | plugin_puts "Beginning URL Purge from ATS..." 33 | plugin_puts "Finding ATS Servers..." 34 | nodes_ats_fqdns = [] 35 | nodes_ats = rest_api.get_rest("/search/node?q=role:#{chef_role}" ) 36 | nodes_ats["rows"].each do |n| 37 | nodes_ats_fqdns << n['automatic']['fqdn'] unless n.nil? 38 | end 39 | 40 | urls.each do |u| 41 | url = u.chomp 42 | plugin_puts "Purging #{url}" 43 | nodes_ats_fqdns.each do |ats| 44 | hostname = URI.parse(url).host 45 | path = URI.parse(url).path 46 | result = `ssh #{ats} 'curl -X PURGE -s -o /dev/null -w \"%{http_code}\" --header \"Host: #{hostname}\" \"http://localhost#{path}\"'` 47 | if result.include?("200") 48 | plugin_puts "--Purged from #{ats} sucessfully" 49 | elsif result.include?("404") 50 | plugin_puts "--Purge from #{ats} not needed, asset not found" 51 | else 52 | plugin_puts_error(url,"--Purge from #{ats} failed") 53 | end 54 | 55 | end 56 | end 57 | end 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/cloudflare.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class CloudFlare < Plugin 6 | name :cloudflare 7 | hooks :cdn_purge 8 | 9 | def perform 10 | safe_require 'uri' 11 | safe_require 'faraday_middleware' 12 | safe_require 'json' 13 | safe_require 'public_suffix' 14 | 15 | login = config.login 16 | api_key = config.api_key 17 | 18 | if login.nil? 19 | plugin_puts "CloudFlare login not specified, Exiting..." 20 | exit 1 21 | end 22 | 23 | if api_key.nil? 24 | plugin_puts "CloudFlare API key not specified, Exiting..." 25 | exit 1 26 | end 27 | 28 | plugin_puts "Beginning URL Purge from CloudFlare..." 29 | 30 | urls.each do |u| 31 | url = u.chomp 32 | plugin_puts "Purging #{url}" 33 | 34 | uri = URI.parse(url) 35 | zone = PublicSuffix.parse(uri.host).domain 36 | 37 | connection = Faraday::Connection.new( 38 | {:url => "https://www.cloudflare.com", 39 | :headers => { :accept => 'application/json', 40 | :user_agent => 'Ipecache' 41 | }, 42 | :ssl => { :verify => true } 43 | }) do |builder| 44 | builder.request :url_encoded 45 | builder.adapter Faraday.default_adapter 46 | end 47 | 48 | response = connection.get("/api_json.html", 49 | { :act => 'zone_file_purge', 50 | :tkn => api_key, 51 | :email => login, 52 | :z => zone, 53 | :url => url 54 | }) 55 | 56 | response_json = JSON.parse(response.body) 57 | response_result = response_json['result'] 58 | 59 | if response_result != 'success' 60 | plugin_puts_error(url,"Purge failed!") 61 | plugin_puts response.body 62 | exit 1 unless continue_on_error 63 | else 64 | plugin_puts "Purge successful!" 65 | end 66 | end 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/cloudfront.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class CloudFront < Plugin 6 | name :cloudfront 7 | hooks :cdn_purge 8 | 9 | def perform 10 | safe_require 'aws-sdk-v1' 11 | safe_require 'uri' 12 | 13 | access_key_id = config.access_key_id 14 | secret_access_key = config.secret_access_key 15 | region = config.region 16 | distributions = config.distributions 17 | batch_size = config.batch_size || 3000 18 | 19 | if access_key_id.nil? 20 | plugin_puts "Cloudfront access id not specified, Exiting..." 21 | exit 1 22 | end 23 | 24 | if secret_access_key.nil? 25 | plugin_puts "Cloudfront access key not specified, Exiting..." 26 | exit 1 27 | end 28 | 29 | if distributions.nil? 30 | plugin_puts "Cloudfront distributions not specified, Exiting..." 31 | exit 1 32 | end 33 | 34 | if region.nil? 35 | plugin_puts "Cloudfront region not specified, Exiting..." 36 | exit 1 37 | end 38 | 39 | plugin_puts "Beginning URL Purge from CloudFront..." 40 | 41 | AWS.config( 42 | :access_key_id => access_key_id, 43 | :secret_access_key => secret_access_key, 44 | :region => region 45 | ) 46 | cf = AWS::CloudFront.new() 47 | 48 | urls.each_slice(batch_size) do |u| 49 | paths = [] 50 | u.each { |x| paths << URI.parse(x).path} 51 | distributions.each do |distri| 52 | plugin_puts "Purging #{u.length} items from #{distri}" 53 | result = cf.client.create_invalidation( 54 | :distribution_id => distri, 55 | :invalidation_batch => { 56 | :paths => { 57 | :quantity => paths.length, 58 | :items => paths 59 | }, 60 | :caller_reference => "Ipecache_#{Time.now}" 61 | } 62 | ) 63 | plugin_puts "#{result[:id]}: #{result[:status]}, #{result[:invalidation_batch][:paths][:items].length} item(s)" 64 | end 65 | plugin_puts "This invalidation costs #{paths.length*0.005} Euro" 66 | end 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/edgecast.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class Edgecast < Plugin 6 | name :edgecast 7 | hooks :cdn_purge 8 | 9 | def perform 10 | safe_require 'uri' 11 | safe_require 'faraday_middleware' 12 | safe_require 'json' 13 | 14 | account_id = config.account_id 15 | api_key = config.api_key 16 | 17 | if account_id.nil? 18 | plugin_puts("Edgecast account id not specified, Exiting...") 19 | exit 1 20 | end 21 | 22 | if api_key.nil? 23 | plugin_puts("Edgecast API key not specified, Exiting...") 24 | exit 1 25 | end 26 | 27 | plugin_puts "Beginning URL Purge from Edgecast..." 28 | 29 | urls.each do |u| 30 | url = u.chomp 31 | plugin_puts ("Purging #{url}") 32 | 33 | connection = Faraday::Connection.new( 34 | {:url => "https://api.edgecast.com", 35 | :headers => { :accept => 'application/json', 36 | :content_type => 'application/json', 37 | :user_agent => 'Ipecache', 38 | :authorization => "TOK:#{api_key}"}, 39 | :ssl => { :verify => true } 40 | }) do |builder| 41 | builder.request :json 42 | builder.adapter Faraday.default_adapter 43 | end 44 | 45 | response = connection.put("/v2/mcc/customers/#{account_id}/edge/purge",{ :MediaPath => url, :MediaType => 8}) 46 | 47 | if response.status != 200 48 | plugin_puts_error(url,"Response Code: #{response.status}") 49 | plugin_puts_error(url,response.body) 50 | exit 1 unless continue_on_error 51 | else 52 | plugin_puts "Purge successful!" 53 | end 54 | end 55 | end 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/fastly.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | require 'net/http' 3 | 4 | module Ipecache 5 | module Plugins 6 | class Fastly < Plugin 7 | name :fastly 8 | hooks :cdn_purge 9 | 10 | def perform 11 | safe_require 'uri' 12 | safe_require 'openssl' 13 | api_key = config.api_key 14 | 15 | if api_key.nil? 16 | plugin_puts("Fastly API key not specified, Exiting...") 17 | exit 1 18 | end 19 | 20 | plugin_puts "Beginning URL Purge from Fastly..." 21 | 22 | urls.each do |u| 23 | url = u.chomp 24 | plugin_puts ("Purging #{url}") 25 | 26 | uri = URI.parse("https://api.fastly.com/purge/#{url}") 27 | 28 | http = Net::HTTP.new(uri.host, uri.port) 29 | http.use_ssl = true 30 | 31 | http.verify_mode = OpenSSL::SSL::VERIFY_PEER 32 | 33 | request = Net::HTTP::Post.new(uri.request_uri) 34 | request.add_field("Accept", "application/json") 35 | request.add_field("User-Agent", "Ipecache") 36 | request.add_field("Fastly-Key", api_key) 37 | 38 | response = http.request(request) 39 | 40 | if response.code.to_i != 200 41 | plugin_puts_error(url,"Response Code: #{response.code}") 42 | plugin_puts_error(url,response.body) 43 | exit 1 unless continue_on_error 44 | else 45 | plugin_puts "Purge successful!" 46 | end 47 | end 48 | end 49 | end 50 | end 51 | end 52 | 53 | class Net::HTTP::Purge < Net::HTTPRequest 54 | METHOD = 'PURGE' 55 | REQUEST_HAS_BODY = false 56 | RESPONSE_HAS_BODY = true 57 | end 58 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/local.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class Local < Plugin 6 | name :local 7 | hooks :proxy_purge 8 | 9 | def perform 10 | safe_require 'uri' 11 | 12 | hosts = config.hosts 13 | use_ssh = config.use_ssh 14 | 15 | if !hosts 16 | plugin_puts "No hosts in config file specified. Exiting..." 17 | exit 1 18 | end 19 | 20 | with = (use_ssh) ? "ssh curl" : "curl"; 21 | 22 | urls.each do |u| 23 | url = u.chomp 24 | plugin_puts ("Purging #{url} through #{with}") 25 | hosts.each do |local| 26 | hostname = URI.parse(url).host 27 | path = URI.parse(url).path 28 | if use_ssh 29 | result = `ssh #{local} 'curl -X PURGE -s -o /dev/null -w \"%{http_code}\" --header \"Host: #{hostname}\" \"http://localhost#{path}\"'` 30 | else 31 | result = `curl -X PURGE -s -o /dev/null -w "%{http_code}" --header "Host: #{hostname}" "http://#{local}#{path}"` 32 | end 33 | if result.include?("200") 34 | plugin_puts "--Purged from #{local} sucessfully" 35 | elsif result.include?("404") 36 | plugin_puts "--Purge from #{local} not needed, asset not found" 37 | else 38 | plugin_puts_error(url,"--Purge from #{local} failed with http_code = #{result}") 39 | end 40 | 41 | end 42 | end 43 | end 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/maxcdn.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class MaxCDN < Plugin 6 | name :maxcdn 7 | hooks :cdn_purge 8 | 9 | def perform 10 | safe_require 'maxcdn' 11 | 12 | [ :alias, :token, :secret, :zone ].each do |key| 13 | confirm!(key) 14 | end 15 | 16 | zone = config.zone.to_i 17 | 18 | plugin_puts "Beginning URL Purge from MaxCDN..." 19 | 20 | api = ::MaxCDN::Client.new(config.alias, config.token, config.secret) 21 | 22 | urls.each do |u| 23 | url = u.chomp 24 | plugin_puts ("Purging #{url}") 25 | 26 | begin 27 | response = api.purge(zone, url) 28 | 29 | if response["code"] != 200 30 | plugin_puts_error(url, "Response Code: #{response["code"]}") 31 | plugin_puts_error(url, response.to_s) 32 | exit 1 unless continue_on_error 33 | else 34 | plugin_puts "Purge successful!" 35 | end 36 | rescue MaxCDN::APIException => e 37 | plugin_puts_error(url, "Response: #{e}") 38 | exit 1 unless continue_on_error 39 | end 40 | end 41 | end 42 | 43 | private 44 | def confirm! key 45 | if config.send(key).nil? 46 | plugin_puts("MaxCDN #{key} not specified, Exiting...") 47 | exit 1 48 | end 49 | end 50 | 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/plugin.rb: -------------------------------------------------------------------------------- 1 | module Ipecache 2 | module Plugins 3 | class Plugin 4 | # This is the name of the plugin. It must correspond to the name in the yaml configuration 5 | # file in order to load this plugin. If an attribute is passed in, the name is set to that 6 | # given value. Otherwise, the name is returned. 7 | def self.name(name = nil) 8 | if name.nil? 9 | class_variable_get(:@@name) 10 | else 11 | class_variable_set(:@@name, name) 12 | end 13 | end 14 | 15 | # This is a convenience method for defining multiple hooks in a single call. 16 | def self.hooks(*the_hooks) 17 | [the_hooks].flatten.each{ |the_hook| hook(the_hook) } 18 | end 19 | 20 | # When defining a hook, we define a method on the instance that corresponds to that 21 | # hook. That will be fired when the hook is fired. 22 | def self.hook(the_hook) 23 | self.send(:define_method, the_hook.to_sym) do 24 | if !quiet_mode 25 | puts "" 26 | end 27 | perform 28 | end 29 | end 30 | 31 | def initialize(options = {}) 32 | @options = { 33 | :payload => {} 34 | }.merge(options) 35 | end 36 | 37 | def enabled? 38 | !(config.nil? || config.enabled == false) 39 | end 40 | 41 | def urls 42 | @options[:urls] 43 | end 44 | 45 | def log_file 46 | @options[:log_file] 47 | end 48 | 49 | def continue_on_error 50 | @options[:continue_on_error] 51 | end 52 | 53 | def quiet_mode 54 | @options[:quiet_mode] 55 | end 56 | 57 | def name 58 | self.class.to_s 59 | end 60 | 61 | def plugin_puts(message) 62 | if !quiet_mode 63 | puts "#{name}: #{message}" 64 | end 65 | end 66 | 67 | def plugin_puts_error(url,message) 68 | if log_file 69 | File.open(log_file, 'a') { |file| file.write("#{Time.now.getutc} #{url} #{name}: #{message}\n") } 70 | end 71 | 72 | if !quiet_mode 73 | puts "#{url} #{name}: #{message}" 74 | end 75 | end 76 | 77 | private 78 | def config 79 | @options[:config].plugins.send(self.class.name.to_sym) unless @options[:config].nil? || @options[:config].plugins.nil? 80 | end 81 | 82 | # Wrapper method around require that attempts to include the associated file. If it does not exist 83 | # or cannot be loaded, an nice error is produced instead of blowing up. 84 | def safe_require(file) 85 | begin 86 | require file 87 | rescue LoadError 88 | raise "You are using a plugin for ipecache that requires #{file}, but you have not installed it. Please either run \"gem install #{file}\", add #{file} to your Gemfile or remove the plugin from your configuration." 89 | end 90 | end 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/swisstxt_cdn.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class SwisstxtCdn < Plugin 6 | name :swisstxt_cdn 7 | hooks :cdn_purge 8 | 9 | def perform 10 | safe_require 'uri' 11 | safe_require 'faraday_middleware' 12 | 13 | plugin_puts "Beginning URL Purge from SWISS TXT CDN..." 14 | 15 | urls.each do |u| 16 | url = u.chomp 17 | plugin_puts ("Purging #{url}") 18 | 19 | begin 20 | conn = connection 21 | unless host = URI.parse(url).host 22 | raise "Invalid URL: No host found in URL. Missing schema?" 23 | end 24 | path = URI.parse(url).path 25 | response = conn.post('/purge', host: host, path: path) 26 | rescue => e 27 | plugin_puts_error(url, e.message) 28 | continue_on_error ? next : exit(1) 29 | end 30 | 31 | if response.status != 200 32 | plugin_puts_error(url, "Response Code: #{response.status}") 33 | plugin_puts_error(url, response.body['error'] || response.body) 34 | exit 1 unless continue_on_error 35 | else 36 | plugin_puts "Purge successful!" 37 | end 38 | end 39 | end 40 | 41 | def connection 42 | if config.api_key.nil? 43 | plugin_puts("SWISS TXT CDN API api_key not specified, Exiting...") 44 | exit 1 45 | end 46 | 47 | if config.api_secret.nil? 48 | plugin_puts("SWISS TXT CDN API api_secret not specified, Exiting...") 49 | exit 1 50 | end 51 | 52 | Faraday.new(url: config.url || 'https://cdn-api.swisstxt.ch') do |conn| 53 | conn.request :url_encoded 54 | conn.headers[:user_agent] = 'Ipecache' 55 | conn.headers[:accept] = 'application/json' 56 | conn.response :json, content_type: /\b(json)$/ 57 | conn.headers['X-API-KEY'] = config.api_key 58 | conn.headers['X-API-SECRET'] = config.api_secret 59 | conn.adapter Faraday.default_adapter 60 | end 61 | end 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /lib/ipecache/plugins/varnish.rb: -------------------------------------------------------------------------------- 1 | require 'ipecache/plugins/plugin' 2 | 3 | module Ipecache 4 | module Plugins 5 | class Varnish < Plugin 6 | name :varnish 7 | hooks :proxy_purge 8 | 9 | def perform 10 | safe_require 'uri' 11 | 12 | hosts = config.hosts 13 | use_ssh = config.use_ssh 14 | action = (config.action.upcase == "PURGE") ? "PURGE" : "BAN" 15 | key = config.auth_key 16 | 17 | if !hosts 18 | plugin_puts "No hosts in config file specified. Exiting..." 19 | exit 1 20 | end 21 | 22 | request = (action == "BAN") ? "Banning" : "Purging" 23 | 24 | with = (use_ssh) ? "ssh curl" : "curl"; 25 | 26 | urls.each do |u| 27 | url = u.chomp.gsub(/\*$/,'').gsub(/\*/,'.*') 28 | plugin_puts ("#{request} #{url} through #{with}") 29 | hosts.each do |varnish| 30 | hostname = URI.parse(url).host 31 | path = URI.parse(url).path 32 | if use_ssh 33 | result = `ssh #{varnish} 'curl -X #{action} -s -o /dev/null -w \"%{http_code}\" --header \"X-BAN-Auth: #{key}\" --header \"Host: #{hostname}\" \"http://localhost#{path}\"'` 34 | else 35 | result = `curl -X #{action} -s -o /dev/null -w "%{http_code}" --header "X-BAN-Auth: #{key}" --header "Host: #{hostname}" "http://#{varnish}#{path}"` 36 | end 37 | if result.include?("200") 38 | plugin_puts "--#{request} from #{varnish} sucessfully" 39 | elsif result.include?("404") 40 | plugin_puts "--#{action} from #{varnish} not needed, asset not found" 41 | else 42 | plugin_puts_error(url,"--#{action} from #{varnish} failed with http_code = #{result}") 43 | end 44 | 45 | end 46 | end 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/ipecache/runner.rb: -------------------------------------------------------------------------------- 1 | require 'app_conf' 2 | require 'json' 3 | 4 | require 'ipecache/plugins' 5 | 6 | module Ipecache 7 | module Runner 8 | module ClassMethods; end 9 | 10 | module InstanceMethods 11 | def ipecache_config 12 | return @ipecache_config unless @ipecache_config.nil? 13 | 14 | @ipecache_config = AppConf.new 15 | load_paths = [ File.expand_path('config/ipecache-config.yml'), '/etc/ipecache-config.yml', File.expand_path('~/.ipecache/ipecache-config.yml') ] 16 | load_paths.each do |load_path| 17 | if File.exists?(load_path) 18 | @ipecache_config.load(load_path) 19 | end 20 | end 21 | 22 | @ipecache_config 23 | end 24 | 25 | def run_plugins(hook) 26 | urls = @urls 27 | log_file = @log_file 28 | continue_on_error = @continue_on_error 29 | quiet_mode = @quiet_mode 30 | Ipecache::Plugins.run( 31 | :config => ipecache_config, 32 | :hook => hook.to_sym, 33 | :urls => urls, 34 | :log_file => log_file, 35 | :continue_on_error => continue_on_error, 36 | :quiet_mode => quiet_mode 37 | ) 38 | end 39 | 40 | def pretty_print_json(json) 41 | JSON.pretty_generate(json) 42 | end 43 | end 44 | 45 | def self.included(receiver) 46 | receiver.extend(ClassMethods) 47 | receiver.send(:include, InstanceMethods) 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /plugins/ATSChef.md: -------------------------------------------------------------------------------- 1 | ATSChef 2 | ======== 3 | Queries chef for nodes in the specified role and purges the URL list from each Apache Traffic Server 4 | 5 | Gem Requirements 6 | ---------------- 7 | This plugin requires the following gems: 8 | 9 | ```ruby 10 | gem 'chef' 11 | ``` 12 | 13 | Hooks 14 | ----- 15 | - `proxy_purge` 16 | 17 | Configuration 18 | ------------- 19 | ```yaml 20 | plugins: 21 | atschef: 22 | knife_config: /my/.chef/knife.rb 23 | chef_role: ATSRole 24 | ``` 25 | 26 | #### knife_config 27 | This is the knife.rb that ipecache can use to search against your Chef server 28 | 29 | - Type: `String` 30 | 31 | #### chef_role 32 | This is the chef role which your ATS servers live in 33 | 34 | - Type: `String` 35 | -------------------------------------------------------------------------------- /plugins/Akamai.md: -------------------------------------------------------------------------------- 1 | Akamai 2 | ======== 3 | Purges URLS from the Akamai CDN using the Content Control Utility API 4 | 5 | Hooks 6 | ----- 7 | - `cdn_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | akamai: 14 | client_secret: xxxxxxx 15 | host: xxxxxxx 16 | access_token: xxxxxxx 17 | client_token: xxxxxxx 18 | ``` 19 | 20 | #### username 21 | This is the username of the Akamai account you want to use 22 | 23 | - Type: `String` 24 | 25 | #### password 26 | This is the password of the Akamai account you want to use 27 | 28 | - Type: `String` 29 | -------------------------------------------------------------------------------- /plugins/CloudFlare.md: -------------------------------------------------------------------------------- 1 | CloudFlare 2 | ========== 3 | Purge URLs from the CloudFlare CDN. 4 | 5 | Hooks 6 | ----- 7 | - `cdn_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | cloudflare: 14 | login: foo@bar.com 15 | api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 16 | ``` 17 | 18 | #### login 19 | This is your standard CloudFlare login. 20 | 21 | - Type: `String` 22 | 23 | #### api_key 24 | Associated API Key, available on the "Account" page. 25 | 26 | - Type: `String` 27 | -------------------------------------------------------------------------------- /plugins/Cloudfront.md: -------------------------------------------------------------------------------- 1 | CloudFront 2 | ========== 3 | Purge URLs from the CloudFront CDN. 4 | 5 | Hooks 6 | ----- 7 | - `cdn_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | cloudfront: 14 | access_key_id: yyyyyyyyyyyyyyyy 15 | secret_access_key: xxxxxxxxxxxxxxxxxx 16 | region: eu-west-1 17 | batch_size: 3000 18 | distributions: 19 | - distribution1 20 | - distribution2 21 | ``` 22 | 23 | #### access_key_id 24 | This is your aws access id 25 | 26 | - Type: `String` 27 | 28 | #### secret_access_key 29 | This is your aws access key 30 | 31 | - Type: `String` 32 | 33 | #### distributions 34 | This is a list of CF distributions 35 | 36 | - Type `Array` 37 | 38 | ### region 39 | This is the AWS region of your CF distributions 40 | 41 | - Type `String` 42 | 43 | ### batch_size 44 | This is the number of items to be included for each invalidation request, default to 3000 (aws max limit) 45 | 46 | - Type `Integer` 47 | -------------------------------------------------------------------------------- /plugins/Edgecast.md: -------------------------------------------------------------------------------- 1 | Edgecast 2 | ======== 3 | Purges URLS from the Edgecast CDN - please note this currently only works with HTTP Small objects. 4 | 5 | Hooks 6 | ----- 7 | - `cdn_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | edgecast: 14 | account_id: 1ABC 15 | api_key: aaaa-aaaaaa-aaaaaa-aaaaa 16 | ``` 17 | 18 | #### account_id 19 | This is your Edgecast account number, found at the top of the Edgecast admin interface 20 | 21 | - Type: `String` 22 | 23 | #### api_key 24 | This is your Edgecast API key 25 | 26 | - Type: `String` 27 | -------------------------------------------------------------------------------- /plugins/Fastly.md: -------------------------------------------------------------------------------- 1 | Fastly 2 | ======== 3 | Purges URLS from the Fastly CDN 4 | 5 | Hooks 6 | ----- 7 | - `cdn_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | fastly: 14 | api_key: ab123ab123ab123ab123ab123ab123 15 | ``` 16 | 17 | #### api_key 18 | This is your fastly API key 19 | 20 | - Type: `String` 21 | -------------------------------------------------------------------------------- /plugins/Local.md: -------------------------------------------------------------------------------- 1 | Local 2 | ======== 3 | Uses a defined set of Hosts from the config and purges the URL list from each Cache Server e.g. Apache Traffic Server or Varnish Cache 4 | 5 | Hooks 6 | ----- 7 | - `proxy_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | local: 14 | hosts: 15 | - cache1.mydomain.com 16 | - cache2.mydomain.com 17 | use_ssh: false 18 | ``` 19 | 20 | #### hosts 21 | This defines an array of Hosts to send the purge request 22 | 23 | - Type: `Array` 24 | 25 | #### use_ssh 26 | This enables a SSH-Wrapper to run the purge request locally on the Cache Server 27 | 28 | - Type: `Boolean` 29 | -------------------------------------------------------------------------------- /plugins/MaxCDN.md: -------------------------------------------------------------------------------- 1 | MaxCDN 2 | ======== 3 | Purges URLS from MaxCDN 4 | 5 | Hooks 6 | ----- 7 | - `cdn_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | maxcdn: 14 | alias: myalias 15 | token: 1A2B 16 | secret: abc123 17 | zone: 1234 18 | ``` 19 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | Plugins Directory 2 | ================= 3 | This folder contains relevant documentation for each KnifeSpork plugin. For more information, usage, and options for an particular plugin, click on the assoicated markdown file in the tree above. 4 | 5 | Creating a Plugin 6 | ----------------- 7 | To create a plugin, start with the following basic boiler template: 8 | 9 | ```ruby 10 | require 'ipecache/plugins/plugin' 11 | 12 | module Ipecache 13 | module Plugins 14 | class MyPlugin < Plugin 15 | name :my_plugin 16 | hooks :my_hooks 17 | 18 | def perform 19 | # your plugin code here 20 | end 21 | end 22 | end 23 | end 24 | ``` 25 | 26 | **Don't forget to update the class name and the `name` at the very top of the class!** 27 | 28 | Hooks 29 | ----- 30 | 31 | Currently, the only hooks called by the ipecache binary are "proxy_purge" (for plugins for "local" proxy servers) and "cdn_purge" (for CDN plugins). These hooks determine whether or not your plugin will be called when the -c and -p options are passed to the ipecache binary. 32 | 33 | Helpers 34 | ------- 35 | The following "helpers" or "methods" are exposed: 36 | 37 | #### safe_require 38 | This method allows you to safely require a gem. This is helpful when your plugin requires an external plugin. It will output a nice error message if the gem cannot be loaded and stop executing. 39 | 40 | #### urls 41 | This method gives you the list of URLS to be purged 42 | 43 | #### plugin_puts 44 | This method prints strings prefixed by the class name of your plugin, for clarity of output 45 | 46 | #### config 47 | This method returns the config associated with the current plugin. For example, if a `spork-config.yml` file looked like this: 48 | 49 | ```yaml 50 | plugins: 51 | my_plugin: 52 | option_1: my_value 53 | option_2: other_value 54 | ``` 55 | 56 | then 57 | 58 | ```text 59 | config.option_1 #=> 'my_value' 60 | config.option_2 #=> 'other_value' 61 | ``` 62 | 63 | This uses `app_conf`, so you access the keys as methods, not `[]`. -------------------------------------------------------------------------------- /plugins/SWISS_TXT_CDN.md: -------------------------------------------------------------------------------- 1 | SWISS TXT CDN 2 | ============= 3 | Purges URLS from the [SWISS TXT CDN](http://www.swisstxt.ch/). 4 | 5 | Hooks 6 | ----- 7 | - `cdn_purge` 8 | 9 | Configuration 10 | ------------- 11 | ```yaml 12 | plugins: 13 | swisstxt_cdn: 14 | api_key: sample_key_e8e55aff-61e3-4588-ab98-4d3ea58be7c8 15 | api_secret: xyz5678xyz5678xyz5678xyz5678xyz5678xyz5678xyz5678 16 | ``` 17 | 18 | #### api_key 19 | This is the api_key of the SWISS TXT CDN account you want to use 20 | 21 | - Type: `String` 22 | 23 | #### api_secret 24 | This is the api_secret of the SWISS TXT CDN account you want to use 25 | 26 | - Type: `String` 27 | 28 | #### url (optional) 29 | The URL of the SWISS TXT CDN API. This parameter defaults to `https://cdn-api.swissttx.ch` and is not required. 30 | 31 | - Type: `String` -------------------------------------------------------------------------------- /plugins/Varnish.md: -------------------------------------------------------------------------------- 1 | Varnish 2 | ======== 3 | Uses a defined set of Hosts from the config and purges/bans the URL list from each Varnish Server 4 | Adapted from the Local plugin 5 | 6 | Hooks 7 | ----- 8 | - `proxy_purge` 9 | 10 | Configuration 11 | ------------- 12 | ```yaml 13 | plugins: 14 | varnish: 15 | hosts: 16 | - cache1.mydomain.com 17 | - cache2.mydomain.com 18 | use_ssh: false 19 | action: ban 20 | auth_key: 21 | ``` 22 | 23 | #### hosts 24 | This defines an array of Hosts to send the purge request 25 | 26 | - Type: `Array` 27 | 28 | #### use_ssh 29 | This enables a SSH-Wrapper to run the purge request locally on the Cache Server 30 | 31 | - Type: `Boolean` 32 | 33 | #### action 34 | This defines whether use BAN or PURGE 35 | 36 | - Type: `String` 37 | 38 | ### auth_key 39 | This defines the authorization key sent in the headers with the request 40 | 41 | - Type: `String` 42 | --------------------------------------------------------------------------------