akamai_ccu 1.5.4 → 1.5.5

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: 590edfc04540966643fb8dcb26d61b1bc1fd472d
4
- data.tar.gz: 786b909ccd366835593fd460dc590d6d2d2b6edd
3
+ metadata.gz: 21b678bb15fc4484478ffd8eafd454a73d64ebf2
4
+ data.tar.gz: aea48ed0449fa22043a6c76dc0d04f8a4a26bde8
5
5
  SHA512:
6
- metadata.gz: 7e08562da9ceb7f72beb90ed9bd38fdae72b23088f28f3c7c47ce964f1dbc5940b85f61d9a805e4632c365fe5529cd202c8e154b3648e5bbe76f04ce7b21543d
7
- data.tar.gz: 27796fd0c26becf2f80a1bfdeba91b5d3b5b8586da1248576e24c3854e9462150234029683a5e66c86ce36faae9e26598612fcd96c512aec20d8d10f90b45e83
6
+ metadata.gz: 7e84ce88cb3bff7b228c5989e9addf4696415dd3c14909203c6a2393a962c2530754905b4f80c8774fecb52dc21b93bf4c6b509f0e0898ec448d094790f2f89c
7
+ data.tar.gz: 44aa80033178853ddbf3234a9e2d6d26581637a18e85449736a0d0ad35108a067559141c1ec7bc2851ea455af4e9477bcf837043d149373e65e8ebeb9c5abfe5
data/README.md CHANGED
@@ -18,7 +18,6 @@
18
18
  * [ccu_invalidate](#ccu_invalidate)
19
19
  * [ccu_delete](#ccu_delete)
20
20
  * [Bulk operation](#bulk-operation)
21
- * [Redirecting output](#redirecting-output)
22
21
  * [Overwriting options](#overwriting-options)
23
22
  * [Logging](#logging)
24
23
  * [Library logger](#library-logger)
@@ -123,14 +122,14 @@ The CCU V3 APIs allow for invalidating contents by URLs or content provider (CP)
123
122
  AkamaiCCU::Wrapper.invalidate_by_url(%w[https://akaa-baseurl-xxx-xxx.luna.akamaiapis.net/index.html])
124
123
 
125
124
  # invalidating resources on production (mind the "!") by CP code
126
- AkamaiCCU::Wrapper.invalidate_by_cpcode!([12345, 98765])
125
+ AkamaiCCU::Wrapper.invalidate_by_cpcode!([12345,98765])
127
126
  ```
128
127
 
129
128
  #### Deleting
130
129
  You can delete contents by URLs or CP codes as well, just be aware of what you're doing:
131
130
  ```ruby
132
131
  # deleting resources on staging by CP codes
133
- AkamaiCCU::Wrapper.delete_by_cpcode([12345, 98765])
132
+ AkamaiCCU::Wrapper.delete_by_cpcode([12345,98765])
134
133
 
135
134
  # deleting resources on production (mind the "!") by URLs
136
135
  AkamaiCCU::Wrapper.delete_by_url!(%w[https://akaa-baseurl-xxx-xxx.luna.akamaiapis.net/main.js])
@@ -139,9 +138,9 @@ AkamaiCCU::Wrapper.delete_by_url!(%w[https://akaa-baseurl-xxx-xxx.luna.akamaiapi
139
138
  #### Response
140
139
  The Net::HTTP response is wrapped by an utility struct:
141
140
  ```ruby
142
- res = AkamaiCCU::Wrapper.invalidate_by_cpcode([12345, 98765])
141
+ res = AkamaiCCU::Wrapper.invalidate_by_cpcode([12345,98765])
143
142
  puts res
144
- # status=201; detail=Request accepted; purge_id=e535071c-26b2-11e7-94d7-276f2f54d938; support_id=17PY1492793544958045-219026624; copletion_at=20170620T11:19:16+0000
143
+ # status=201; detail=Request accepted; support_id=17PY1498402073417329-261436608; purge_id=44ac266e-59b5-11e7-84ca-75d9dd540c3b; copletion_at=2017-06-20 12:19:16 +0100
145
144
  ```
146
145
 
147
146
  ### CLI
@@ -151,12 +150,12 @@ You can use the CLI by:
151
150
  Calling the help for the specific action:
152
151
  ```shell
153
152
  ccu_invalidate -h
154
- Usage: ccu_invalidate --secret=~/.edgerc --production --cp=12345,98765
155
- -s, --secret=SECRET Load secret data by file
153
+ Usage: ccu_invalidate --secret=~/tokens.txt --production --cp=12345,98765
154
+ -s, --secret=SECRET Load secret by file (default to ~/.edgerc)
156
155
  -c, --cp=CP Specify contents by provider (CP) codes
157
156
  -u, --url=URL Specify contents by URLs
158
157
  -b, --bulk=BULK Specify bulk contents in a file
159
- --headers=HEADERS Specify HTTP headers to sign
158
+ --headers=HEADERS Specify any HTTP headers to sign
160
159
  -p, --production Purge on production network
161
160
  -h, --help Prints this help
162
161
  ```
@@ -164,16 +163,15 @@ Usage: ccu_invalidate --secret=~/.edgerc --production --cp=12345,98765
164
163
  #### ccu_invalidate
165
164
  Do request for contents invalidation by:
166
165
  ```shell
167
- ccu_invalidate --secret=~/.edgerc \
166
+ ccu_invalidate --secret=~/tokens.txt \
168
167
  --url=https://akaa-baseurl-xxx-xxx.luna.akamaiapis.net/main.css,https://akaa-baseurl-xxx-xxx.luna.akamaiapis.net/main.js \
169
168
  --production
170
169
  ```
171
170
 
172
171
  #### ccu_delete
173
- Do request for contents deletion by:
172
+ Do request for contents deletion by (load secret from ~/.edgerc implicitly):
174
173
  ```shell
175
- ccu_delete --secret=~/tokens.txt \
176
- --cp=12345,98765 \
174
+ ccu_delete --cp=12345,98765 \
177
175
  --headers=Accept,Content-Length
178
176
  ```
179
177
 
@@ -190,13 +188,7 @@ https://akaa-baseurl-xxx-xxx.luna.akamaiapis.net/static/index.html
190
188
 
191
189
  Specify the bulk option by using the file path:
192
190
  ```shell
193
- ccu_invalidate --secret=~/.edgerc --bulk=urls.txt
194
- ```
195
-
196
- #### Redirecting output
197
- In case you're calling the CLI from another program (like your Jenkins script), just redirect the output to your log file:
198
- ```shell
199
- ccu_invalidate --secret=~/.edgerc --cp=12345,98765 >> mylog.log
191
+ ccu_invalidate --bulk=urls.txt
200
192
  ```
201
193
 
202
194
  #### Overwriting options
@@ -233,7 +225,13 @@ AkamaiCCU::Wrapper.logger = Logger.new(STDOUT)
233
225
  CLI uses a logger writing to `STDOUT` by default with an `INFO` level.
234
226
  In case you want to control the log level, just pass an environment variable to the script:
235
227
  ```shell
236
- LOG_LEVEL=DEBUG ccu_invalidate --secret=~/.edgerc --cp=12345,98765
228
+ LOG_LEVEL=DEBUG ccu_invalidate --cp=12345,98765
229
+ ```
230
+
231
+ ##### Redirecting output
232
+ In case you're calling the CLI from another program (like your Jenkins script), just redirect the output to your log file:
233
+ ```shell
234
+ ccu_invalidate --cp=12345,98765 >> mylog.log
237
235
  ```
238
236
 
239
237
  ### Possible Issues
@@ -241,7 +239,7 @@ LOG_LEVEL=DEBUG ccu_invalidate --secret=~/.edgerc --cp=12345,98765
241
239
  #### Invalid timestamp
242
240
  You could get a `bad request` response like this:
243
241
  ```shell
244
- status=400; title=Bad request; detail=Invalid timestamp; request_id=2ce206fd; method=POST; requested_at=2017-06-21T12:33:10Z
242
+ status=400; title=Bad request; detail=Invalid timestamp; support_id=5079982a; described_by=https://problems.purge.akamaiapis.net/-/pep-authn/request-error
245
243
  ```
246
244
 
247
245
  This happens since Akamai APIs only tolerate a clock skew of at most 30 seconds to defend against certain network attacks (described [here](https://community.akamai.com/docs/DOC-1336)).
data/lib/akamai_ccu.rb CHANGED
@@ -1,31 +1,5 @@
1
1
  $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
2
 
3
- require "base64"
4
- require "json"
5
- require "openssl"
6
3
  require "akamai_ccu/version"
7
4
  require "akamai_ccu/wrapper"
8
5
  require "akamai_ccu/cli"
9
-
10
- module AkamaiCCU
11
- extend self
12
-
13
- GET = :Get
14
- POST = :Post
15
- SSL = "https"
16
- JSON_HEADER = { "Content-Type" => "application/json" }
17
-
18
- def format_utc(time)
19
- time.utc.strftime("%Y%m%dT%H:%M:%S+0000")
20
- end
21
-
22
- def sign(data)
23
- digest = OpenSSL::Digest::SHA256.new.digest(data)
24
- Base64.encode64(digest).strip
25
- end
26
-
27
- def sign_HMAC(key:, data:)
28
- digest = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, key, data)
29
- Base64.encode64(digest).strip
30
- end
31
- end
@@ -49,7 +49,7 @@ module AkamaiCCU
49
49
 
50
50
  private def parser
51
51
  OptionParser.new do |opts|
52
- opts.banner = "Usage: ccu_#{@action} --secret=~/.edgerc --production --cp=12345,98765"
52
+ opts.banner = "Usage: ccu_#{@action} --secret=~/tokens.txt --production --cp=12345,98765"
53
53
 
54
54
  opts.on("-sSECRET", "--secret=SECRET", "Load secret by file (default to ~/.edgerc)") do |secret|
55
55
  @secret = File.expand_path(secret)
@@ -3,6 +3,11 @@ require "openssl"
3
3
 
4
4
  module AkamaiCCU
5
5
  class Client
6
+ GET = :Get
7
+ POST = :Post
8
+ SSL = "https"
9
+ JSON_HEADER = { "Content-Type" => "application/json" }
10
+
6
11
  attr_reader :net_klass, :host
7
12
 
8
13
  def initialize(host:, net_klass: Net::HTTP)
@@ -4,83 +4,38 @@ module AkamaiCCU
4
4
  class Response
5
5
  BAD_STATUS = 400
6
6
 
7
- def self.factory(body)
8
- response = new(body)
9
- case response
10
- when ->(res) { res.successful? }
11
- Ack.new(body)
12
- else
13
- Error.new(body)
14
- end
15
- end
16
-
17
- attr_reader :body, :status, :detail
7
+ attr_reader :body, :title, :status, :detail, :support_id, :purge_id, :decribed_by, :completion_at
18
8
 
19
- def initialize(body = {})
9
+ def initialize(body = {}, time = Time.now)
20
10
  @body = parse(body)
11
+ @title = @body["title"]
21
12
  @status = @body.fetch("httpStatus") { @body.fetch("status", BAD_STATUS) }
22
13
  @detail = @body["detail"]
14
+ @support_id = @body.fetch("supportId") { @body["requestId"] }
15
+ @purge_id = @body["purgeId"]
16
+ @described_by = @body.fetch("describedBy") { @body["type"] }
17
+ @estimated_secs = @body["estimatedSeconds"]
18
+ @completion_at = time + @estimated_secs.to_i if @estimated_secs
23
19
  end
24
20
 
25
21
  def successful?
26
22
  (@status.to_i / 100) == 2
27
23
  end
28
24
 
29
- private def parse(body)
30
- return body if body.is_a? Hash
31
- JSON.parse(body)
32
- end
33
- end
34
-
35
- class Error < Response
36
- attr_reader :type, :title, :request_id, :instance, :method, :server_ip, :client_ip
37
-
38
- def initialize(body)
39
- super(body)
40
- @type = @body["type"]
41
- @title = @body["title"]
42
- @request_id = @body["requestId"]
43
- @instance = @body["instance"]
44
- @method = @body["method"]
45
- @serverIp = @body["serverIp"]
46
- @clientIp = @body["clientIp"]
47
- @requested_at = @body["requestTime"]
48
- end
49
-
50
- def requested_at
51
- return nil unless @requested_at
52
- Time.parse(@requested_at)
53
- end
54
-
55
25
  def to_s
56
26
  %W[status=#{@status}].tap do |a|
57
27
  a << "title=#{@title}" if @title
58
28
  a << "detail=#{@detail}" if @detail
59
- a << "request_id=#{@request_id}" if @request_id
60
- a << "method=#{@method}" if @method
61
- a << "requested_at=#{@requested_at}" if @requested_at
29
+ a << "support_id=#{@support_id}" if @support_id
30
+ a << "purge_id=#{@purge_id}" if @purge_id
31
+ a << "described_by=#{@described_by}" if @described_by
32
+ a << "copletion_at=#{@completion_at}" if @completion_at
62
33
  end.join("; ")
63
34
  end
64
- end
65
35
 
66
- class Ack < Response
67
- attr_reader :purge_id, :estimated_secs, :support_id, :completion_at
68
-
69
- def initialize(body, time = Time.now)
70
- super(body)
71
- @purge_id = @body["purgeId"]
72
- @estimated_secs = @body["estimatedSeconds"]
73
- @support_id = @body["supportId"]
74
- @completion_at = time + @estimated_secs.to_i
75
- end
76
-
77
- def to_s
78
- %W[status=#{@status}].tap do |a|
79
- a << "detail=#{@detail}" if @detail
80
- a << "purge_id=#{@purge_id}" if @purge_id
81
- a << "support_id=#{@support_id}" if @support_id
82
- a << "copletion_at=#{AkamaiCCU.format_utc(@completion_at)}" if @completion_at
83
- end.join("; ")
36
+ private def parse(body)
37
+ return body if body.is_a? Hash
38
+ JSON.parse(body)
84
39
  end
85
40
  end
86
41
  end
@@ -1,5 +1,7 @@
1
- require "uri"
1
+ require "base64"
2
+ require "openssl"
2
3
  require "securerandom"
4
+ require "uri"
3
5
 
4
6
  module AkamaiCCU
5
7
  class Secret
@@ -9,6 +11,20 @@ module AkamaiCCU
9
11
 
10
12
  class FileContentError < ArgumentError; end
11
13
 
14
+ def self.format_utc(time)
15
+ time.utc.strftime("%Y%m%dT%H:%M:%S+0000")
16
+ end
17
+
18
+ def self.sign(data)
19
+ digest = OpenSSL::Digest::SHA256.new.digest(data)
20
+ Base64.encode64(digest).strip
21
+ end
22
+
23
+ def self.sign_HMAC(key, data)
24
+ digest = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, key, data)
25
+ Base64.encode64(digest).strip
26
+ end
27
+
12
28
  def self.by_file(name = "~/.edgerc", time = Time.now)
13
29
  path = File.expand_path(name)
14
30
  return unless File.exist?(path)
@@ -32,17 +48,17 @@ module AkamaiCCU
32
48
  @client_token = client_token
33
49
  @max_body = max_body.to_i
34
50
  @nonce = nonce
35
- @timestamp = AkamaiCCU.format_utc(time)
51
+ @timestamp = self.class.format_utc(time)
36
52
  end
37
53
 
38
54
  def touch
39
55
  @nonce = SecureRandom.uuid
40
- @timestamp = AkamaiCCU.format_utc(Time.now)
56
+ @timestamp = self.class.format_utc(Time.now)
41
57
  self
42
58
  end
43
59
 
44
60
  def signed_key
45
- AkamaiCCU.sign_HMAC(key: @client_secret, data: @timestamp)
61
+ self.class.sign_HMAC(@client_secret, @timestamp)
46
62
  end
47
63
 
48
64
  def auth_header
@@ -1,5 +1,4 @@
1
1
  require "forwardable"
2
- require "uri"
3
2
  require "akamai_ccu/secret"
4
3
 
5
4
  module AkamaiCCU
@@ -42,7 +41,7 @@ module AkamaiCCU
42
41
  private def signed_body
43
42
  return "" unless body?
44
43
  truncated = body[0...max_body]
45
- AkamaiCCU.sign(truncated)
44
+ @secret.class.sign(truncated)
46
45
  end
47
46
 
48
47
  private def signature_data
@@ -58,7 +57,7 @@ module AkamaiCCU
58
57
  end
59
58
 
60
59
  private def signature
61
- AkamaiCCU.sign_HMAC(key: signed_key, data: signature_data.join(TAB))
60
+ @secret.class.sign_HMAC(signed_key, signature_data.join(TAB))
62
61
  end
63
62
 
64
63
  def signed_header
@@ -1,3 +1,3 @@
1
1
  module AkamaiCCU
2
- VERSION = "1.5.4"
2
+ VERSION = "1.5.5"
3
3
  end
@@ -1,3 +1,4 @@
1
+ require "json"
1
2
  require "akamai_ccu/client"
2
3
  require "akamai_ccu/endpoint"
3
4
  require "akamai_ccu/signer"
@@ -45,7 +46,7 @@ module AkamaiCCU
45
46
  self.class.logger.debug { "request: uri=#{request.path}; body=#{request.body}; authorization=#{request["Authorization"]}" }
46
47
  end
47
48
  self.class.logger.debug { "response: inspect=#{response.inspect}; body=#{response.body}" }
48
- response_klass.factory(response.body)
49
+ response_klass.new(response.body)
49
50
  end
50
51
  end
51
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: akamai_ccu
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 1.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - costajob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-24 00:00:00.000000000 Z
11
+ date: 2017-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler