fastly 0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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