cloudflare 4.0.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,28 +34,33 @@ module Cloudflare
34
34
  @record = record || get.result
35
35
  end
36
36
 
37
- def update_content(content)
37
+ def update_content(content, **options)
38
38
  response = put(
39
39
  type: @record[:type],
40
40
  name: @record[:name],
41
- content: content
41
+ content: content,
42
+ **options
42
43
  )
43
-
44
+
44
45
  @value = response.result
45
46
  end
46
-
47
+
47
48
  def type
48
49
  value[:type]
49
50
  end
50
-
51
+
51
52
  def name
52
53
  value[:name]
53
54
  end
54
-
55
+
55
56
  def content
56
57
  value[:content]
57
58
  end
58
-
59
+
60
+ def proxied
61
+ value[:proxied]
62
+ end
63
+
59
64
  def to_s
60
65
  "#{@record[:name]} #{@record[:type]} #{@record[:content]}"
61
66
  end
@@ -63,29 +68,20 @@ module Cloudflare
63
68
 
64
69
  class Records < Representation
65
70
  include Paginate
66
-
71
+
67
72
  def representation
68
73
  Record
69
74
  end
70
-
75
+
71
76
  TTL_AUTO = 1
72
77
 
73
78
  def create(type, name, content, **options)
74
- message = self.post(type: type, name: name, content: content, **options)
75
-
76
- id = message.result[:id]
77
- resource = @resource.with(path: id)
78
-
79
- return representation.new(resource, metadata: message.headers, value: message.result)
79
+ represent_message(self.post(type: type, name: name, content: content, **options))
80
80
  end
81
-
81
+
82
82
  def find_by_name(name)
83
83
  each(name: name).first
84
84
  end
85
-
86
- def find_by_id(id)
87
- Record.new(@resource.with(path: id))
88
- end
89
85
  end
90
86
  end
91
87
  end
@@ -29,15 +29,15 @@ module Cloudflare
29
29
  def mode
30
30
  value[:mode]
31
31
  end
32
-
32
+
33
33
  def notes
34
34
  value[:notes]
35
35
  end
36
-
36
+
37
37
  def configuration
38
38
  value[:configuration]
39
39
  end
40
-
40
+
41
41
  def to_s
42
42
  "#{configuration[:value]} - #{mode} - #{notes}"
43
43
  end
@@ -45,14 +45,14 @@ module Cloudflare
45
45
 
46
46
  class Rules < Representation
47
47
  include Paginate
48
-
48
+
49
49
  def representation
50
50
  Rule
51
51
  end
52
-
52
+
53
53
  def set(mode, value, notes: nil, target: 'ip')
54
54
  notes ||= "cloudflare gem [#{mode}] #{Time.now.strftime('%m/%d/%y')}"
55
-
55
+
56
56
  message = self.post({
57
57
  mode: mode.to_s,
58
58
  notes: notes,
@@ -61,17 +61,10 @@ module Cloudflare
61
61
  value: value.to_s,
62
62
  }
63
63
  })
64
-
65
- id = message.result[:id]
66
- resource = @resource.with(path: id)
67
-
68
- return representation.new(resource, metadata: message.headers, value: message.result)
69
- end
70
-
71
- def find_by_id(id)
72
- Rule.new(@resource.with(path: id))
64
+
65
+ represent_message(message)
73
66
  end
74
-
67
+
75
68
  def each_by_value(value, &block)
76
69
  each(configuration_value: value, &block)
77
70
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This implements the Worker KV Store API
4
+ # https://api.cloudflare.com/#workers-kv-namespace-properties
5
+
6
+ require_relative '../paginate'
7
+ require_relative '../representation'
8
+
9
+ module Cloudflare
10
+ module KV
11
+ class Key < Representation
12
+ def name
13
+ value[:name]
14
+ end
15
+ end
16
+
17
+ class Keys < Representation
18
+ include Paginate
19
+
20
+ def representation
21
+ Key
22
+ end
23
+ end
24
+
25
+ class Namespace < Representation
26
+ def delete_value(name)
27
+ value_representation(name).delete.success?
28
+ end
29
+
30
+ def id
31
+ value[:id]
32
+ end
33
+
34
+ def keys
35
+ self.with(Keys, path: 'keys')
36
+ end
37
+
38
+ def read_value(name)
39
+ value_representation(name).value
40
+ end
41
+
42
+ def rename(new_title)
43
+ put(title: new_title)
44
+ value[:title] = new_title
45
+ end
46
+
47
+ def title
48
+ value[:title]
49
+ end
50
+
51
+ def write_value(name, value)
52
+ value_representation(name).put(value).success?
53
+ end
54
+
55
+ private
56
+
57
+ def value_representation(name)
58
+ self.with(Representation, path: "values/#{name}")
59
+ end
60
+ end
61
+
62
+ class Namespaces < Representation
63
+ include Paginate
64
+
65
+ def representation
66
+ Namespace
67
+ end
68
+
69
+ def create(title)
70
+ represent_message(post(title: title))
71
+ end
72
+
73
+ def find_by_title(title)
74
+ each.find {|namespace| namespace.title == title }
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,15 +1,15 @@
1
1
  # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  # of this software and associated documentation files (the "Software"), to deal
5
5
  # in the Software without restriction, including without limitation the rights
6
6
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
7
  # copies of the Software, and to permit persons to whom the Software is
8
8
  # furnished to do so, subject to the following conditions:
9
- #
9
+ #
10
10
  # The above copyright notice and this permission notice shall be included in
11
11
  # all copies or substantial portions of the Software.
12
- #
12
+ #
13
13
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
14
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
15
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -21,34 +21,32 @@
21
21
  module Cloudflare
22
22
  module Paginate
23
23
  include Enumerable
24
-
25
- def empty?
26
- self.value.empty?
27
- end
28
-
29
- def representation
30
- Representation
31
- end
32
-
24
+
33
25
  def each(page: 1, per_page: 50, **parameters)
34
26
  return to_enum(:each, page: page, per_page: per_page, **parameters) unless block_given?
35
-
27
+
36
28
  while true
37
29
  zones = @resource.get(self.class, page: page, per_page: per_page, **parameters)
38
-
30
+
39
31
  break if zones.empty?
40
-
32
+
41
33
  Array(zones.value).each do |attributes|
42
- resource = @resource.with(path: attributes[:id])
43
-
44
- yield representation.new(resource, metadata: zones.metadata, value: attributes)
34
+ yield represent(zones.metadata, attributes)
45
35
  end
46
-
36
+
47
37
  page += 1
48
-
38
+
49
39
  # Was this the last page?
50
- break if zones.value.count < per_page
40
+ break if zones.value.size < per_page
51
41
  end
52
42
  end
43
+
44
+ def empty?
45
+ self.value.empty?
46
+ end
47
+
48
+ def find_by_id(id)
49
+ representation.new(@resource.with(path: id))
50
+ end
53
51
  end
54
52
  end
@@ -29,62 +29,79 @@ module Cloudflare
29
29
  class RequestError < StandardError
30
30
  def initialize(resource, errors)
31
31
  super("#{resource}: #{errors.map{|attributes| attributes[:message]}.join(', ')}")
32
-
32
+
33
33
  @representation = representation
34
34
  end
35
-
35
+
36
36
  attr_reader :representation
37
37
  end
38
-
38
+
39
39
  class Message
40
40
  def initialize(response)
41
41
  @response = response
42
42
  @body = response.read
43
+
44
+ # Some endpoints return the value instead of a message object (like KV reads)
45
+ @body = { success: true, result: @body } unless @body.is_a?(Hash)
43
46
  end
44
-
47
+
45
48
  attr :response
46
49
  attr :body
47
-
50
+
48
51
  def headers
49
52
  @response.headers
50
53
  end
51
-
54
+
52
55
  def result
53
56
  @body[:result]
54
57
  end
55
-
58
+
56
59
  def read
57
60
  @body[:result]
58
61
  end
59
-
62
+
60
63
  def results
61
64
  Array(result)
62
65
  end
63
-
66
+
64
67
  def errors
65
68
  @body[:errors]
66
69
  end
67
-
70
+
68
71
  def messages
69
72
  @body[:messages]
70
73
  end
71
-
74
+
72
75
  def success?
73
76
  @body[:success]
74
77
  end
75
78
  end
76
-
79
+
77
80
  class Representation < Async::REST::Representation
78
81
  def process_response(*)
79
82
  message = Message.new(super)
80
-
83
+
81
84
  unless message.success?
82
85
  raise RequestError.new(@resource, message.errors)
83
86
  end
84
-
87
+
85
88
  return message
86
89
  end
87
-
90
+
91
+ def representation
92
+ Representation
93
+ end
94
+
95
+ def represent(metadata, attributes)
96
+ resource = @resource.with(path: attributes[:id])
97
+
98
+ representation.new(resource, metadata: metadata, value: attributes)
99
+ end
100
+
101
+ def represent_message(message)
102
+ represent(message.headers, message.result)
103
+ end
104
+
88
105
  def to_hash
89
106
  if value.is_a?(Hash)
90
107
  return value
@@ -21,6 +21,8 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  require 'async/rspec'
24
+ require 'async/http/proxy'
25
+
24
26
  require_relative '../../cloudflare'
25
27
 
26
28
  module Cloudflare
@@ -35,10 +37,20 @@ module Cloudflare
35
37
  let(:email) {ENV['CLOUDFLARE_EMAIL']}
36
38
  let(:key) {ENV['CLOUDFLARE_KEY']}
37
39
 
38
- let(:connection) {@connection = Cloudflare.connect(key: key, email: email)}
40
+ let(:connection) do
41
+ if proxy_url = ENV['CLOUDFLARE_PROXY']
42
+ proxy_endpoint = Async::HTTP::Endpoint.parse(proxy_url)
43
+ @client = Async::HTTP::Client.new(proxy_endpoint)
44
+ @connection = Cloudflare.connect(@client.proxied_endpoint(DEFAULT_ENDPOINT), key: key, email: email)
45
+ else
46
+ @client = nil
47
+ @connection = Cloudflare.connect(key: key, email: email)
48
+ end
49
+ end
39
50
 
40
51
  after do
41
52
  @connection&.close
53
+ @client&.close
42
54
  end
43
55
  end
44
56
  end
@@ -22,5 +22,5 @@
22
22
  # THE SOFTWARE.
23
23
 
24
24
  module Cloudflare
25
- VERSION = '4.0.1'
25
+ VERSION = '4.2.0'
26
26
  end
@@ -25,22 +25,27 @@
25
25
  require_relative 'representation'
26
26
  require_relative 'paginate'
27
27
 
28
+ require_relative 'custom_hostnames'
28
29
  require_relative 'firewall'
29
30
  require_relative 'dns'
30
31
  require_relative 'logs'
31
32
 
32
33
  module Cloudflare
33
34
  class Zone < Representation
35
+ def custom_hostnames
36
+ self.with(CustomHostnames, path: 'custom_hostnames')
37
+ end
38
+
34
39
  def dns_records
35
- DNS::Records.new(@resource.with(path: 'dns_records'))
40
+ self.with(DNS::Records, path: 'dns_records')
36
41
  end
37
42
 
38
43
  def firewall_rules
39
- Firewall::Rules.new(@resource.with(path: 'firewall/access_rules/rules'))
44
+ self.with(Firewall::Rules, path: 'firewall/access_rules/rules')
40
45
  end
41
46
 
42
47
  def logs
43
- Logs::Received.new(@resource.with(path: 'logs/received'))
48
+ self.with(Logs::Received, path: 'logs/received')
44
49
  end
45
50
 
46
51
  DEFAULT_PURGE_CACHE_PARAMS = {
@@ -48,9 +53,9 @@ module Cloudflare
48
53
  }.freeze
49
54
 
50
55
  def purge_cache(parameters = DEFAULT_PURGE_CACHE_PARAMS)
51
- message = self.with(path: 'purge_cache').post(parameters)
56
+ self.with(Zone, path: 'purge_cache').post(parameters)
52
57
 
53
- return message.success?
58
+ return self
54
59
  end
55
60
 
56
61
  def name
@@ -66,22 +71,13 @@ module Cloudflare
66
71
  def representation
67
72
  Zone
68
73
  end
69
-
74
+
70
75
  def create(name, account, jump_start = false)
71
- message = self.post(name: name, account: account.to_hash, jump_start: jump_start)
72
-
73
- id = message.result[:id]
74
- resource = @resource.with(path: id)
75
-
76
- return representation.new(resource, metadata: message.headers, value: message.result)
76
+ represent_message(self.post(name: name, account: account.to_hash, jump_start: jump_start))
77
77
  end
78
-
78
+
79
79
  def find_by_name(name)
80
80
  each(name: name).first
81
81
  end
82
-
83
- def find_by_id(id)
84
- Zone.new(@resource.with(path: id))
85
- end
86
82
  end
87
83
  end