codily 0.1.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,195 @@
1
+ require 'fastly'
2
+ require 'codily/utils'
3
+
4
+ module Codily
5
+ module Elements
6
+ class Base
7
+ class AlreadyDefined < StandardError; end
8
+
9
+ def self.parent_class
10
+ nil
11
+ end
12
+
13
+ def self.path
14
+ @path ||= [].tap do |path|
15
+ ptr = self
16
+ while ptr = ptr.parent_class
17
+ path.unshift ptr
18
+ end
19
+ end
20
+ end
21
+
22
+ def self.name_for_attr
23
+ @attr_name ||= self.name.split('::').last.gsub(/[A-Z]/, '_\0').gsub(/^_/, '').downcase
24
+ end
25
+
26
+ def self.def_attr(*attrs)
27
+ attrs.each do |attr|
28
+ define_method(attr) do |obj = nil|
29
+ getset attr, obj
30
+ end
31
+ end
32
+ end
33
+
34
+ def self.defaults(kv = nil)
35
+ if kv
36
+ @defaults = defaults.merge(kv)
37
+ else
38
+ @defaults ||= {}
39
+ end
40
+ end
41
+
42
+ def initialize(root, obj, &block)
43
+ @root = root
44
+
45
+ case obj
46
+ when Hash
47
+ @hash = obj
48
+ when Fastly::Base
49
+ @fastly_obj = obj
50
+ @hash = Utils.symbolize_keys(obj.as_hash)
51
+
52
+ @hash.delete :id
53
+ @hash.each_key do |k|
54
+ @hash.delete k if @hash[k].nil?
55
+ end
56
+ else
57
+ raise TypeError
58
+ end
59
+
60
+ instance_eval(&block) if block
61
+
62
+ setup
63
+ end
64
+
65
+ attr_reader :root
66
+ attr_accessor :fastly_obj
67
+
68
+ def inspect
69
+ "#<#{self.class}:#{self.key.inspect}/#{Hash[self.as_hash.to_a.sort_by{ |_| _.first.to_s }]}>"
70
+ end
71
+
72
+ def parent_class
73
+ self.class.parent_class
74
+ end
75
+
76
+ def parent_key
77
+ nil
78
+ end
79
+
80
+ def parent
81
+ return nil if parent_class.nil?
82
+ root.list_element(parent_class)[parent_key] or raise '[bug?] no parent element'
83
+ end
84
+
85
+ def parents
86
+ parents = []
87
+ ptr = self
88
+ while ptr = ptr.parent
89
+ parents.unshift ptr
90
+ end
91
+ return parents
92
+ end
93
+
94
+ def id
95
+ fastly_obj && fastly_obj.respond_to?(:id) ? fastly_obj.id : nil
96
+ end
97
+
98
+ def name(str = nil)
99
+ getset :name, str
100
+ end
101
+
102
+ def dsl_args
103
+ [name]
104
+ end
105
+
106
+ def key
107
+ name
108
+ end
109
+
110
+ def as_hash
111
+ self.class.defaults.merge @hash
112
+ end
113
+
114
+ def as_dsl_hash
115
+ as_hash.tap do |x|
116
+ x.delete :name
117
+ end
118
+ end
119
+
120
+ private
121
+
122
+ def getset(key, obj)
123
+ if obj.nil?
124
+ @hash[key]
125
+ else
126
+ raise AlreadyDefined if @hash.key?(key)
127
+ @hash[key] = obj
128
+ end
129
+ end
130
+
131
+ def add(key, obj)
132
+ @hash[key] ||= []
133
+ @hash[key] << obj
134
+ end
135
+
136
+ def add_element(key, klass, obj = {}, key2 = :name, &block)
137
+ element = klass.new(root, obj, &block)
138
+ root.add_element(element)
139
+ add(key, element.__send__(key2))
140
+ end
141
+
142
+ def add_refer_element(key, klass, obj = {}, key2 = :name, &block)
143
+ elem = refer_element(klass, obj, key2, &block)
144
+ add(key, elem.__send__(key2))
145
+ end
146
+
147
+ def set_refer_element(key, klass, obj = {}, key2 = :name, &block)
148
+ elem = refer_element(klass, obj, key2, &block)
149
+ getset(key, elem.__send__(key2))
150
+ end
151
+
152
+ def refer_element(klass, obj, key2, &block)
153
+ list = root.list_element(klass)
154
+ element = klass.new(root, obj, &block)
155
+ element_query = element.__send__(key2)
156
+ candidate = list.each_value.find { |_| _.__send__(key2) == element_query }
157
+ if candidate
158
+ if block
159
+ raise AlreadyDefined
160
+ end
161
+ else
162
+ root.add_element(element)
163
+ end
164
+
165
+ candidate || element
166
+ end
167
+
168
+ def setup
169
+ end
170
+
171
+ private
172
+
173
+ def delete_if_empty!(*keys)
174
+ keys.each do |k|
175
+ @hash.delete k if @hash[k] && @hash[k].empty?
176
+ end
177
+ end
178
+
179
+ def force_integer!(*keys)
180
+ keys.each do |k|
181
+ if @hash[k]
182
+ @hash[k] = case @hash[k]
183
+ when true
184
+ 1
185
+ when false
186
+ 0
187
+ else
188
+ @hash[k].to_i
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,32 @@
1
+ require 'codily/elements/service_belongging_base'
2
+ require 'codily/elements/condition'
3
+
4
+ module Codily
5
+ module Elements
6
+ class CacheSetting < ServiceBelonggingBase
7
+ def_attr *%i(
8
+ action
9
+ stale_ttl
10
+ ttl
11
+ )
12
+
13
+ def setup
14
+ delete_if_empty! *%i(
15
+ cache_condition
16
+ )
17
+ force_integer! *%i(
18
+ ttl
19
+ stale_ttl
20
+ )
21
+ end
22
+
23
+ def cache_condition(name = nil, &block)
24
+ set_refer_element(:cache_condition, Condition, {name: name, type: 'CACHE', _service_name: self.service_name}, &block)
25
+ end
26
+
27
+ def fastly_class
28
+ Fastly::CacheSetting
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ require 'codily/elements/service_belongging_base'
2
+
3
+ module Codily
4
+ module Elements
5
+ class Condition < ServiceBelonggingBase
6
+ def_attr *%i(
7
+ comment
8
+ priority
9
+ statement
10
+ )
11
+
12
+ def type(obj = nil)
13
+ getset :type, obj.to_s.upcase
14
+ end
15
+
16
+ def fastly_class
17
+ Fastly::Condition
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ require 'codily/elements/service_belongging_base'
2
+
3
+ module Codily
4
+ module Elements
5
+ class Dictionary < ServiceBelonggingBase
6
+ def_attr *%i(
7
+ )
8
+
9
+ def fastly_class
10
+ Fastly::Dictionary
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ require 'codily/elements/service_belongging_base'
2
+
3
+ module Codily
4
+ module Elements
5
+ class Domain < ServiceBelonggingBase
6
+ def_attr *%i(
7
+ comment
8
+ )
9
+
10
+ def setup
11
+ delete_if_empty! :comment
12
+ end
13
+
14
+ def fastly_class
15
+ Fastly::Domain
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ module Codily
2
+ module Elements
3
+ module FileLoadable
4
+ def self.included(klass)
5
+ klass.instance_eval do
6
+ def def_file_loadable_attr(*attrs)
7
+ attrs.each do |attr|
8
+ define_method(attr) do |obj = nil|
9
+ getset attr, file_loadable(obj)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def file_loadable(obj)
19
+ case obj
20
+ when Hash
21
+ if obj.key?(:inline)
22
+ return obj[:inline]
23
+ end
24
+ if obj.key?(:file)
25
+ return File.read(obj[:file])
26
+ end
27
+ raise ArgumentError
28
+ else
29
+ return obj.to_s
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ require 'codily/elements/service_belongging_base'
2
+ require 'codily/elements/condition'
3
+
4
+ module Codily
5
+ module Elements
6
+ class Gzip < ServiceBelonggingBase
7
+ def content_types(o = nil)
8
+ o = case o
9
+ when nil
10
+ nil
11
+ when String
12
+ o
13
+ when Array
14
+ o.join(' ')
15
+ end
16
+ getset :content_types, o
17
+ end
18
+
19
+ def extensions(o = nil)
20
+ o = case o
21
+ when nil
22
+ nil
23
+ when String
24
+ o
25
+ when Array
26
+ o.join(' ')
27
+ end
28
+ getset :extensions, o
29
+ end
30
+
31
+ def setup
32
+ delete_if_empty! :cache_condition
33
+ end
34
+
35
+ def cache_condition(name = nil, &block)
36
+ set_refer_element(:cache_condition, Condition, {name: name, type: 'CACHE', _service_name: self.service_name}, &block)
37
+ end
38
+
39
+ def fastly_class
40
+ Fastly::Gzip
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,57 @@
1
+ require 'codily/elements/service_belongging_base'
2
+ require 'codily/elements/condition'
3
+
4
+ module Codily
5
+ module Elements
6
+ class Header < ServiceBelonggingBase
7
+ def_attr *%i(
8
+ action
9
+ src
10
+ dst
11
+ ignore_if_set
12
+ priority
13
+ regex
14
+ substitution
15
+ type
16
+ )
17
+
18
+ def setup
19
+ delete_if_empty! *%i(
20
+ regex
21
+ substitution
22
+ )
23
+ force_integer! *%i(
24
+ priority
25
+ ignore_if_set
26
+ )
27
+ if @hash.key?(:ignore_if_set)
28
+ @hash[:ignore_if_set] = @hash[:ignore_if_set] == 1
29
+ end
30
+ end
31
+
32
+ def as_hash
33
+ super.tap do |x|
34
+ if x.key?(:ignore_if_set)
35
+ x[:ignore_if_set] = !!x[:ignore_if_set] ? 1 : 0
36
+ end
37
+ end
38
+ end
39
+
40
+ def cache_condition(name = nil, &block)
41
+ set_refer_element(:cache_condition, Condition, {name: name, _service_name: self.service_name}, &block)
42
+ end
43
+
44
+ def request_condition(name = nil, &block)
45
+ set_refer_element(:request_condition, Condition, {name: name, _service_name: self.service_name}, &block)
46
+ end
47
+
48
+ def response_condition(name = nil, &block)
49
+ set_refer_element(:response_condition, Condition, {name: name, _service_name: self.service_name}, &block)
50
+ end
51
+
52
+ def fastly_class
53
+ Fastly::Header
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,40 @@
1
+ require 'codily/elements/service_belongging_base'
2
+
3
+ module Codily
4
+ module Elements
5
+ class Healthcheck < ServiceBelonggingBase
6
+ def_attr *%i(
7
+ check_interval
8
+ comment
9
+ expected_response
10
+ host
11
+ http_version
12
+ initial
13
+ method
14
+ path
15
+ threshold
16
+ timeout
17
+ window
18
+ )
19
+
20
+ defaults(
21
+ threshold: 1,
22
+ window: 2,
23
+ http_version: "1.1",
24
+ timeout: 5000,
25
+ method: "HEAD",
26
+ expected_response: 200,
27
+ check_interval: 60000,
28
+ initial: 1,
29
+ )
30
+
31
+ def setup
32
+ delete_if_empty! :comment
33
+ end
34
+
35
+ def fastly_class
36
+ Fastly::Healthcheck
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,67 @@
1
+ require 'codily/elements/service_belongging_base'
2
+ require 'codily/elements/condition'
3
+
4
+ require 'codily/fastly_ext'
5
+
6
+ module Codily
7
+ module Elements
8
+ class RequestSetting < ServiceBelonggingBase
9
+ def_attr *%i(
10
+ action
11
+ bypass_busy_wait
12
+ default_host
13
+ force_miss
14
+ force_ssl
15
+ geo_headers
16
+ hash_keys
17
+ max_stale_age
18
+ timer_support
19
+ xff
20
+ )
21
+
22
+ defaults(
23
+ force_ssl: nil,
24
+ force_miss: nil,
25
+ timer_support: nil,
26
+ bypass_busy_wait: nil,
27
+ )
28
+
29
+ def setup
30
+ delete_if_empty! *%i(
31
+ default_host
32
+ hash_keys
33
+ request_condition
34
+ )
35
+
36
+ force_integer! *%i(
37
+ force_ssl
38
+ force_miss
39
+ timer_support
40
+ bypass_busy_wait
41
+ max_stale_age
42
+ )
43
+
44
+ # NOTE: They can be 'N/A' (null) on app.fastly.com, but can't be back to N/A after changed to Y or N once?
45
+ %i(force_ssl force_miss timer_support bypass_busy_wait).each do |k|
46
+ @hash[k] = @hash[k] == 1 if @hash.key?(k)
47
+ end
48
+ end
49
+
50
+ def as_hash
51
+ super.tap do |x|
52
+ %i(force_ssl force_miss timer_support bypass_busy_wait).each do |k|
53
+ x[k] = !!x[k] ? 1 : 0 if x.key?(k) && !x[k].nil?
54
+ end
55
+ end
56
+ end
57
+
58
+ def request_condition(name = nil, &block)
59
+ set_refer_element(:request_condition, Condition, {name: name, type: 'REQUEST', _service_name: self.service_name}, &block)
60
+ end
61
+
62
+ def fastly_class
63
+ Fastly::RequestSetting
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,51 @@
1
+ require 'codily/elements/service_belongging_base'
2
+ require 'codily/elements/condition'
3
+ require 'codily/elements/file_loadable'
4
+
5
+ module Codily
6
+ module Elements
7
+ class ResponseObject < ServiceBelonggingBase
8
+ include FileLoadable
9
+
10
+ def_attr *%i(
11
+ content_type
12
+ status
13
+ response
14
+ cache_condtiion
15
+ request_condition
16
+ )
17
+
18
+ defaults(
19
+ content: "",
20
+ content_type: "",
21
+ response: "",
22
+ )
23
+
24
+ def setup
25
+ delete_if_empty! *%i(
26
+ content
27
+ content_type
28
+ response
29
+ cache_condition
30
+ request_condition
31
+ )
32
+ end
33
+
34
+ def content(obj = nil)
35
+ getset :content, file_loadable(obj)
36
+ end
37
+
38
+ def cache_condition(name = nil, &block)
39
+ set_refer_element(:cache_condition, Condition, {name: name, type: 'CACHE', _service_name: self.service_name}, &block)
40
+ end
41
+
42
+ def request_condition(name = nil, &block)
43
+ set_refer_element(:request_condition, Condition, {name: name, type: 'REQUEST', _service_name: self.service_name}, &block)
44
+ end
45
+
46
+ def fastly_class
47
+ Fastly::ResponseObject
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,85 @@
1
+ require 'codily/elements/base'
2
+ require 'codily/elements/backend'
3
+ require 'codily/elements/cache_setting'
4
+ require 'codily/elements/condition'
5
+ require 'codily/elements/dictionary'
6
+ require 'codily/elements/domain'
7
+ require 'codily/elements/gzip'
8
+ require 'codily/elements/header'
9
+ require 'codily/elements/healthcheck'
10
+ require 'codily/elements/request_setting'
11
+ require 'codily/elements/response_object'
12
+ require 'codily/elements/vcl'
13
+ require 'codily/elements/settings'
14
+
15
+ module Codily
16
+ module Elements
17
+ class Service < Base
18
+ def setup
19
+ @hash.delete :customer_id
20
+ @hash.delete :versions
21
+ delete_if_empty! :comment
22
+ end
23
+
24
+ def name(name = nil)
25
+ getset :name, name
26
+ end
27
+
28
+ def comment(comment = nil)
29
+ getset :comment, comment
30
+ end
31
+
32
+ def backend(name, &block)
33
+ root.add_element Backend.new(root, {name: name, _service_name: self.name}, &block)
34
+ end
35
+
36
+ def cache_setting(name, &block)
37
+ root.add_element CacheSetting.new(root, {name: name, _service_name: self.name}, &block)
38
+ end
39
+
40
+ def condition(name, &block)
41
+ root.add_element Condition.new(root, {name: name, _service_name: self.name}, &block)
42
+ end
43
+
44
+ def dictionary(name, &block)
45
+ root.add_element Dictionary.new(root, {name: name, _service_name: self.name}, &block)
46
+ end
47
+
48
+ def domain(name, &block)
49
+ root.add_element Domain.new(root, {name: name, _service_name: self.name}, &block)
50
+ end
51
+
52
+ def gzip(name, &block)
53
+ root.add_element Gzip.new(root, {name: name, _service_name: self.name}, &block)
54
+ end
55
+
56
+ def header(name, &block)
57
+ root.add_element Header.new(root, {name: name, _service_name: self.name}, &block)
58
+ end
59
+
60
+ def healthcheck(name, &block)
61
+ root.add_element Healthcheck.new(root, {name: name, _service_name: self.name}, &block)
62
+ end
63
+
64
+ def request_setting(name, &block)
65
+ root.add_element RequestSetting.new(root, {name: name, _service_name: self.name}, &block)
66
+ end
67
+
68
+ def response_object(name, &block)
69
+ root.add_element ResponseObject.new(root, {name: name, _service_name: self.name}, &block)
70
+ end
71
+
72
+ def vcl(name, &block)
73
+ root.add_element Vcl.new(root, {name: name, _service_name: self.name}, &block)
74
+ end
75
+
76
+ def settings(kv)
77
+ root.add_element Settings.new(root, {_service_name: self.name}.merge(kv))
78
+ end
79
+
80
+ def fastly_class
81
+ Fastly::Service
82
+ end
83
+ end
84
+ end
85
+ end