fastly 0.5

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,99 @@
1
+ class Fastly
2
+ # An individual host you want to serve assets off
3
+ class Backend < BelongsToServiceAndVersion
4
+ attr_accessor :service_id, :name, :address, :ipv4, :ipv6, :hostname, :use_ssl, :client_cert, :port,
5
+ :connect_timeout, :first_byte_timeout, :between_bytes_timeout, :error_threshold, :max_conn, :weight, :comment
6
+
7
+ ##
8
+ # :attr: service_id
9
+ #
10
+ # The id of the service this belongs to.
11
+ #
12
+
13
+ ##
14
+ # :attr: version
15
+ #
16
+ # The number of the version this belongs to.
17
+ #
18
+
19
+ ##
20
+ # :attr: name
21
+ #
22
+ # The name of this backend.
23
+ #
24
+
25
+ ##
26
+ # :attr: address
27
+ #
28
+ # A magic field - will automagically be set to whichever of ipv4, ipv6 or hostname is currently set.
29
+ #
30
+ # Conversely if you set the address field then the correct field from ipv4, ipv6 or hostname will be set.
31
+ #
32
+
33
+ ##
34
+ # :attr: ipv4
35
+ #
36
+ # the ipv4 address of the host to serve assets (this, hostname or ipv6 must be set)
37
+ #
38
+
39
+ ##
40
+ # :attr: ipv6
41
+ #
42
+ # the ipv6 address of the host to serve assets (this, hostname or ipv4 must be set)
43
+ #
44
+
45
+ ##
46
+ # :attr: hostname
47
+ #
48
+ # the hostname to serve assets from (this, ipv4 or ipv6 must be set)
49
+ #
50
+
51
+ ##
52
+ # :attr: port
53
+ #
54
+ # the port to connect to (default 80)
55
+ #
56
+
57
+ ##
58
+ # :attr: use_ssl
59
+ #
60
+ # whether to use ssl to get to the backend (default 0 i.e false)
61
+ #
62
+
63
+ ##
64
+ # :attr: connect_timeout
65
+ #
66
+ # how long in milliseconds to wait for a connect before declaring the backend out of rotation (default 1,000)
67
+ #
68
+
69
+ ##
70
+ # :attr: first_byte_timeout
71
+ #
72
+ # how long in milliseconds to wait for the first bytes before declaring the host out of rotation (default 15,000)
73
+ #
74
+
75
+ ##
76
+ # :attr: between_bytes_timeout
77
+ #
78
+ # how long in milliseconds to wait between bytes before declaring the backend out of rotation (default 10,000)
79
+ #
80
+
81
+ ##
82
+ # :attr: error_threshold
83
+ #
84
+ # how many errors before declaring the backend out of rotation (default 0, 0 meaning turned off)
85
+ #
86
+
87
+ ##
88
+ # :attr: max_conn
89
+ #
90
+ # the maximum number of connections to this backend (default 20)
91
+ #
92
+
93
+ ##
94
+ # :attr: weight
95
+ #
96
+ # the weight assigned to this backend (default 100)
97
+
98
+ end
99
+ end
@@ -0,0 +1,62 @@
1
+
2
+ class Fastly
3
+ # Base class for all Fastly objects
4
+ class Base # :nodoc: all
5
+ attr_accessor :fetcher
6
+
7
+ def initialize(opts, fetcher)
8
+ @keys = []
9
+ opts.each do |key,val|
10
+ next unless self.respond_to? "#{key}="
11
+ self.send("#{key}=", val)
12
+ @keys.push(key)
13
+ end
14
+ self.fetcher = fetcher
15
+ end
16
+
17
+ # Save this object
18
+ def save!
19
+ fetcher.update(self.class, self)
20
+ end
21
+
22
+ # Delete this object
23
+ def delete!
24
+ fetcher.delete(self.class, self)
25
+ end
26
+
27
+ ##
28
+ # :nodoc:
29
+ def as_hash
30
+ ret = {}
31
+ @keys.each do |key|
32
+ ret[key] = self.send("#{key}") unless key =~ /^_/;
33
+ end
34
+ ret
35
+ end
36
+
37
+ def self.path
38
+ self.to_s.downcase.split("::")[-1]
39
+ end
40
+
41
+ def self.get_path(id)
42
+ "/#{path}/#{id}"
43
+ end
44
+
45
+ def self.post_path(opts={})
46
+ "/#{path}"
47
+ end
48
+
49
+ def self.list_path(opts={})
50
+ post_path(opts)
51
+ end
52
+
53
+ def self.put_path(obj)
54
+ get_path(obj.id)
55
+ end
56
+
57
+ def self.delete_path(obj)
58
+ put_path(obj)
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ class Fastly
2
+ class BelongsToServiceAndVersion < Base
3
+ # Return the Service object this belongs to
4
+ def service
5
+ @service ||= fetcher.get(Fastly::Service, service_id)
6
+ end
7
+
8
+ # Set the Version object this belongs to
9
+ def version=(version)
10
+ @version = version
11
+ end
12
+
13
+ # Get the Version object this belongs to
14
+ def version
15
+ @version_obj ||= fetcher.get(Fastly::Version, service_id, version_number)
16
+ end
17
+
18
+ # Get the number of the Version this belongs to
19
+ def version_number
20
+ @version
21
+ end
22
+
23
+ private
24
+
25
+ def self.get_path(service, version, name)
26
+ "/service/#{service}/version/#{version}/#{path}/#{name}"
27
+ end
28
+
29
+ def self.post_path(opts)
30
+ "/service/#{opts[:service_id]}/version/#{opts[:version]}/#{path}"
31
+ end
32
+
33
+ def self.put_path(obj)
34
+ get_path(obj.service_id, obj.version_number,obj.name)
35
+ end
36
+
37
+ def self.delete_path(obj)
38
+ put_path(obj)
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,160 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'json'
4
+ require 'cgi'
5
+ require 'pp'
6
+ require 'uri'
7
+
8
+ class Fastly
9
+ # The UserAgent to communicate with the API
10
+ class Client #:nodoc: all
11
+ begin
12
+ require 'curb-fu'
13
+ CURB_FU=true
14
+ rescue LoadError
15
+ CURB_FU=false
16
+ end
17
+
18
+ attr_accessor :http, :api_key, :user, :password, :cookie
19
+
20
+ def initialize(opts)
21
+ [:api_key, :user, :password].each do |key|
22
+ self.send("#{key}=", opts[key]) if opts.has_key?(key)
23
+ end
24
+ base = opts[:base_url] || "https://api.fastly.com"
25
+ port = opts[:base_port] || 80
26
+ uri = URI.parse(base)
27
+ scheme = uri.scheme
28
+ host = uri.host
29
+ curb = opts.has_key?(:use_curb) ? !!opts[:use_curb] && CURB_FU : CURB_FU
30
+ self.http = curb ? Fastly::Client::Curl.new(host, port) : Net::HTTP.new(host, port)
31
+ self.http.use_ssl = (scheme == "https")
32
+ return self unless fully_authed?
33
+
34
+ # If we're fully authed (i.e username and password ) then we need to log in
35
+ resp = self.http.post('/login', make_params(:user => user, :password => password))
36
+ raise Fastly::Unauthorized unless resp.success?
37
+ self.cookie = resp['set-cookie']
38
+ content = JSON.parse(resp.body)
39
+ #return self, content['user'], content['content']
40
+ self
41
+ end
42
+
43
+
44
+ def authed?
45
+ !api_key.nil? || fully_authed?
46
+ end
47
+
48
+ # Some methods require full username and password rather than just auth token
49
+ def fully_authed?
50
+ !(user.nil? || password.nil?)
51
+ end
52
+
53
+ def get(path, params={})
54
+ path += "?"+make_params(params) unless params.empty?
55
+ resp = self.http.get(path, headers)
56
+ return nil if 404 == resp.status
57
+ raise Fastly::Error, resp.message unless resp.success?
58
+ JSON.parse(resp.body)
59
+ end
60
+
61
+ def post(path, params={})
62
+ post_and_put(:post, path, params)
63
+ end
64
+
65
+ def put(path, params={})
66
+ post_and_put(:put, path, params)
67
+ end
68
+
69
+ def delete(path)
70
+ resp = self.http.delete(path, headers)
71
+ return resp.success?
72
+ end
73
+
74
+ private
75
+
76
+ def post_and_put(method, path, params={})
77
+ query = make_params(params)
78
+ resp = self.http.send(method, path, query, headers.merge( 'Content-Type' => "application/x-www-form-urlencoded"))
79
+ raise Fastly::Error, resp.message unless resp.success?
80
+ JSON.parse(resp.body)
81
+ end
82
+
83
+ def headers
84
+ (fully_authed? ? { 'Cookie' => cookie } : { 'X-Fastly-Key' => api_key }).merge( 'Content-Accept' => 'application/json')
85
+ end
86
+
87
+ def make_params(params)
88
+ params.map { |key,val|
89
+ next if val.nil?
90
+ unless val.is_a?(Hash)
91
+ "#{CGI.escape(key.to_s)}=#{CGI.escape(val.to_s)}"
92
+ else
93
+ val.map { |sub_key, sub_val|
94
+ new_key = "#{key}[#{sub_key}]"
95
+ "#{CGI.escape(new_key)}=#{CGI.escape(sub_val.to_s)}"
96
+ }
97
+ end
98
+ }.flatten.delete_if { |v| v.nil? }.join("&")
99
+ end
100
+
101
+ # :nodoc: all
102
+ class Curl
103
+ attr_accessor :host, :port, :protocol
104
+
105
+ def initialize(host, port=80)
106
+ self.host = host
107
+ self.port = port
108
+ self.protocol = 'https'
109
+ end
110
+
111
+ def get(path, headers={})
112
+ CurbFu.get({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
113
+ end
114
+
115
+ def post(path, params, headers={})
116
+ CurbFu.post({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol }, params)
117
+ end
118
+
119
+ def put(path, params, headers={})
120
+ CurbFu.put({ :host => host, :port => port, :path => path, :headers => headers, :params => params, :protocol => protocol }, params)
121
+ end
122
+
123
+ def delete(path, headers={})
124
+ CurbFu.delete({ :host => host, :port => port, :path => path, :headers => headers, :protocol => protocol })
125
+ end
126
+
127
+ def use_ssl=(ssl)
128
+ self.protocol = ssl ? 'https' : 'http'
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ # :nodoc: all
135
+ class Net::HTTPResponse
136
+ def success?
137
+ return Net::HTTPSuccess === self
138
+ end
139
+
140
+ def status
141
+ return self.code.to_i
142
+ end
143
+ end
144
+
145
+
146
+
147
+ # :nodoc: all
148
+ class CurbFu::Response::Base
149
+ def get_fields(key)
150
+ if ( match = @headers.find{|k,v| k.downcase == key.downcase} )
151
+ [match.last].flatten
152
+ else
153
+ []
154
+ end
155
+ end
156
+
157
+ def [](key)
158
+ get_fields(key).last
159
+ end
160
+ end
@@ -0,0 +1,26 @@
1
+ class Fastly
2
+ # A Customer account
3
+ class Customer < Base
4
+ attr_accessor :id, :name, :owner_id
5
+
6
+ ##
7
+ # :attr: id
8
+ #
9
+ # The id of this customer
10
+
11
+ ##
12
+ # :attr: name
13
+ #
14
+ # The name of this customer
15
+
16
+ ##
17
+ # :attr: owner_id
18
+ #
19
+ # The id of the user that owns this customer
20
+
21
+ # Return a user object representing the owner of this Customer
22
+ def owner
23
+ self.fetcher.get(User,self.owner_id)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,47 @@
1
+ class Fastly
2
+ # A logical collection of backends - for example all the asset servers in one data center
3
+ class Director < BelongsToServiceAndVersion
4
+ attr_accessor :service_id, :name, :type, :comment, :retries, :capacity, :quorom
5
+
6
+ ##
7
+ # :attr: service
8
+ #
9
+ # The id of the service this belongs to.
10
+ #
11
+
12
+ ##
13
+ # :attr: version
14
+ #
15
+ # The number of the version this belongs to.
16
+ #
17
+
18
+ ##
19
+ # :attr: name
20
+ #
21
+ # The domain name of this domain
22
+ #
23
+
24
+ ##
25
+ # :attr: type
26
+ #
27
+ # what kind of Load Balancer group (currently always 1 meaning random)
28
+ #
29
+
30
+ ##
31
+ # :attr: retries
32
+ #
33
+ # how many backends to search if it fails (default 5)
34
+ #
35
+
36
+ ##
37
+ # :attr: quorum
38
+ #
39
+ # the percentage of capacity that needs to be up for a director to be considered up (default 75)
40
+ #
41
+
42
+ ##
43
+ # :attr: comment
44
+ #
45
+ # a free form comment field
46
+ end
47
+ end
@@ -0,0 +1,29 @@
1
+ class Fastly
2
+ # A domain name you want to map to a service
3
+ class Domain < BelongsToServiceAndVersion
4
+ attr_accessor :service_id, :name, :comment
5
+
6
+ ##
7
+ # :attr: service_id
8
+ #
9
+ # The id of the service this belongs to.
10
+ #
11
+
12
+ ##
13
+ # :attr: version
14
+ #
15
+ # The number of the version this belongs to.
16
+ #
17
+
18
+ ##
19
+ # :attr: name
20
+ #
21
+ # The domain name of this domain
22
+ #
23
+
24
+ ##
25
+ # :attr: comment
26
+ #
27
+ # a free form comment field
28
+ end
29
+ end