rackconnect 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +44 -0
  6. data/Rakefile +5 -0
  7. data/lib/rackconnect.rb +14 -0
  8. data/lib/rackconnect/lib/auth.rb +27 -0
  9. data/lib/rackconnect/lib/bulk_nodes.rb +48 -0
  10. data/lib/rackconnect/lib/bulkable_model.rb +22 -0
  11. data/lib/rackconnect/lib/constants.rb +6 -0
  12. data/lib/rackconnect/lib/model.rb +72 -0
  13. data/lib/rackconnect/lib/request.rb +52 -0
  14. data/lib/rackconnect/lib/singleton_model.rb +19 -0
  15. data/lib/rackconnect/models/cloud_network.rb +7 -0
  16. data/lib/rackconnect/models/load_balancer_pool.rb +8 -0
  17. data/lib/rackconnect/models/load_balancer_pool_details.rb +8 -0
  18. data/lib/rackconnect/models/load_balancer_pool_node.rb +8 -0
  19. data/lib/rackconnect/models/load_balancer_pool_node_details.rb +10 -0
  20. data/lib/rackconnect/models/public_ip.rb +8 -0
  21. data/lib/rackconnect/models/server_group.rb +8 -0
  22. data/lib/rackconnect/models/server_group_details.rb +8 -0
  23. data/lib/rackconnect/models/server_group_node.rb +8 -0
  24. data/lib/rackconnect/models/server_group_node_details.rb +10 -0
  25. data/lib/rackconnect/version.rb +3 -0
  26. data/rackconnect.gemspec +29 -0
  27. data/spec/rackconnect/models/cloud_network_spec.rb +25 -0
  28. data/spec/rackconnect/models/load_balancer_pool_details_spec.rb +25 -0
  29. data/spec/rackconnect/models/load_balancer_pool_node_details.rb +23 -0
  30. data/spec/rackconnect/models/load_balancer_pool_node_details_spec.rb +45 -0
  31. data/spec/rackconnect/models/load_balancer_pool_node_spec.rb +37 -0
  32. data/spec/rackconnect/models/load_balancer_pool_spec.rb +39 -0
  33. data/spec/rackconnect/models/public_ip_spec.rb +45 -0
  34. data/spec/rackconnect/models/server_group_details_spec.rb +14 -0
  35. data/spec/rackconnect/models/server_group_node_details_spec.rb +45 -0
  36. data/spec/rackconnect/models/server_group_node_spec.rb +38 -0
  37. data/spec/rackconnect/models/server_group_spec.rb +53 -0
  38. data/spec/spec_helper.rb +25 -0
  39. data/spec/vcr/apiary/auth.yml +76 -0
  40. data/spec/vcr/apiary/lbpn_create.yml +52 -0
  41. data/spec/vcr/apiary/lbpnd_get_details.yml +86 -0
  42. data/spec/vcr/apiary/load_balancer_bulk_add_nodes.yml +58 -0
  43. data/spec/vcr/apiary/load_balancer_bulk_remove_nodes.yml +97 -0
  44. data/spec/vcr/apiary/load_balancer_pool.yml +57 -0
  45. data/spec/vcr/apiary/load_balancer_pool_details.yml +57 -0
  46. data/spec/vcr/apiary/load_balancer_pool_node.yml +48 -0
  47. data/spec/vcr/apiary/load_balancer_pool_node_destroy.yml +42 -0
  48. data/spec/vcr/apiary/load_balancer_pool_node_details.yml +57 -0
  49. data/spec/vcr/apiary/load_balancer_pool_nodes.yml +60 -0
  50. data/spec/vcr/apiary/load_balancer_pools.yml +85 -0
  51. data/spec/vcr/apiary/network.yml +51 -0
  52. data/spec/vcr/apiary/networks.yml +53 -0
  53. data/spec/vcr/apiary/pool.yml +57 -0
  54. data/spec/vcr/apiary/pools.yml +85 -0
  55. data/spec/vcr/apiary/public_ip.yml +66 -0
  56. data/spec/vcr/apiary/public_ip_create.yml +70 -0
  57. data/spec/vcr/apiary/public_ip_destroy.yml +42 -0
  58. data/spec/vcr/apiary/public_ips.yml +68 -0
  59. data/spec/vcr/apiary/public_ips_for_server.yml +68 -0
  60. data/spec/vcr/apiary/server_group.yml +57 -0
  61. data/spec/vcr/apiary/server_group_bulk_add_nodes.yml +58 -0
  62. data/spec/vcr/apiary/server_group_bulk_remove_nodes.yml +97 -0
  63. data/spec/vcr/apiary/server_group_create.yml +60 -0
  64. data/spec/vcr/apiary/server_group_destroy.yml +42 -0
  65. data/spec/vcr/apiary/server_group_details.yml +92 -0
  66. data/spec/vcr/apiary/server_group_node.yml +48 -0
  67. data/spec/vcr/apiary/server_group_node_destroy.yml +42 -0
  68. data/spec/vcr/apiary/server_group_node_details.yml +57 -0
  69. data/spec/vcr/apiary/server_group_nodes.yml +60 -0
  70. data/spec/vcr/apiary/server_groups.yml +85 -0
  71. data/spec/vcr/apiary/sgnd_for_server.yml +66 -0
  72. data/spec/vcr/apiary/sgnn_create.yml +52 -0
  73. metadata +260 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f5a9759a1d36db1510fff83485be35ed425f6443
4
+ data.tar.gz: cb1287257964f0433849cc8aadfb2acdaaece1c2
5
+ SHA512:
6
+ metadata.gz: 982de393f52d2809456ae5fddd009fda29620687456fc0cb527f3df3720608b147fa9ecee588667992f63c9ec8f29de10d8036e427b87a0bde48e33ea673549a
7
+ data.tar.gz: e478c1c917e279f8d378ca8deada8bd7a8bccc8f6b952f05b6981433b6581e826c4af57e68d67f87e5f9d178dd4740bee7993b498183b7d024e34baad2dd1a36
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+
16
+ lib/bootstrap.rb
17
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rackconnect.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Matt Darby
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Rackconnect
2
+
3
+ RackConnect provides an isolated path for network traffic to traverse between your cloud and dedicated environments located within the same region. To accomplish this, RackConnect relies on Rackspace Cloud Networks on the cloud side and dedicated network devices on the dedicated side of your environment.
4
+
5
+ Rackspace is introducing RackConnect v3.0, the latest release of our innovative hybrid connectivity offering that enables you to select and combine the best features of our dedicated and cloud hosting offerings into one all-encompassing solution. With version 3.0, you can design your computing environment to take advantage of the latest benefits in cloud computing—flexibility, scalability, elasticity—along with the benefits of traditional dedicated hosting—enhanced security and performance characteristics. RackConnect is compatible with our dedicated Managed and Intensive service levels and our cloud Managed Operations and Managed Infrastructure service levels, giving you the ability to select the level of Fanatical Support® that you need to properly manage your hybrid environment.
6
+
7
+ ## Basic Usage
8
+ Rackconnect follows an ActiveModel-esque pattern that most rubyists will feel familiar with:
9
+
10
+ Rackconnect::Auth.new({
11
+ api_key: "",
12
+ username: ""
13
+ })
14
+
15
+ # Get an array of your CloudNetworks
16
+ networks = Rackconnect::CloudNetworks.all
17
+
18
+ network = Rackconnect::CloudNetwork.find(UUID)
19
+
20
+ new_net = Rackconnect::CloudNetwork.create{...})
21
+
22
+ new_net.destroy
23
+
24
+
25
+ ## Models
26
+ * CloudNetwork
27
+ * LoadBalancerPool
28
+ * LoadBalancerPoolNode
29
+ * LoadBalancerPoolNodeDetails
30
+ * Public IPs
31
+ * ServerGroup
32
+ * ServerGroupNode
33
+ * ServerGroupNodeDetails
34
+
35
+ ## Notes
36
+ * Rackconnect will only work with the RackConnect v3 API (current)
37
+
38
+ ## Tech Info
39
+ * [Main Docs](http://www.rackspace.com/knowledge_center/getting-started/rackconnect)
40
+ * [API Docs](http://docs.rcv3.apiary.io/)
41
+ * [FAQ](http://www.rackspace.com/knowledge_center/article/rackconnect-v30-faq)
42
+ * [Limitations](http://www.rackspace.com/knowledge_center/article/rackconnect-v30-limitations)
43
+ * [Requirements](http://www.rackspace.com/knowledge_center/article/rackconnect-v30-requirements)
44
+ * [Support](http://www.rackspace.com/knowledge_center/article/getting-rackconnect-support)
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :c do
4
+ exec "irb -r rackconnect -I ./lib"
5
+ end
@@ -0,0 +1,14 @@
1
+ module Rackconnect
2
+
3
+ class << self
4
+ attr_accessor :token, :tenant_id
5
+ end
6
+
7
+ end
8
+
9
+ # Load after token/tenant_id setup
10
+ require "rackconnect/version"
11
+ require "rest-client"
12
+
13
+ Dir['./lib/rackconnect/lib/*.rb'].each{ |f| require f }
14
+ Dir['./lib/rackconnect/models/*.rb'].each{ |f| require f }
@@ -0,0 +1,27 @@
1
+ class Rackconnect::Auth
2
+
3
+ def initialize(options={})
4
+ api_key = options[:api_key]
5
+ username = options[:username]
6
+
7
+ params = {
8
+ :auth => {
9
+ "RAX-KSKEY:apiKeyCredentials" => {
10
+ "apiKey" => api_key,
11
+ "username" => username
12
+ }
13
+ }
14
+ }.to_json
15
+
16
+ resp = RestClient.post Rackconnect::IDENTITY_URL, params, content_type: :json, accept: :json
17
+ body = JSON.parse(resp)
18
+
19
+ Rackconnect.token = body["access"]["token"]["id"]
20
+ Rackconnect.tenant_id = body["access"]["token"]["tenant"]["id"]
21
+ end
22
+
23
+ def to_s
24
+ {auth_token: Rackconnect.token, tenant_id: Rackconnect.tenant_id}
25
+ end
26
+
27
+ end
@@ -0,0 +1,48 @@
1
+ module Rackconnect::BulkNodes
2
+
3
+ def self.included(base)
4
+ base.send :include, Rackconnect::Model
5
+ base.send :include, InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def add_nodes(ids)
10
+ body = ids.inject({}) do |hash, id|
11
+ h = {}
12
+ h[key] = {id: id}
13
+ h["server_group"] = {id: self.id}
14
+ hash.merge(h)
15
+ end.to_json
16
+
17
+ path = self.class.instance_variable_get("@_endpoint") + "/nodes" # sorry
18
+ resp = Rackconnect::Request.post(path, body: body)
19
+ resp.body.map{ |obj| node_class.new(json: obj) }
20
+ end
21
+
22
+ def remove_nodes(ids)
23
+ body = ids.inject({}) do |hash, id|
24
+ hash.merge({
25
+ cloud_server: {id: id},
26
+ server_group: {id: self.id}
27
+ }).to_json
28
+ end
29
+
30
+ path = self.class.instance_variable_get("@_endpoint") + "/nodes" # sorry
31
+ Rackconnect::Request.delete(path)
32
+ end
33
+ end
34
+
35
+ def node_class
36
+ str = server_based? ? "ServerGroup" : "LoadBalancerPool"
37
+ Kernel.const_get "Rackconnect::#{str}Node"
38
+ end
39
+
40
+ def key
41
+ server_based? ? "cloud_server" : "load_balancer_pool"
42
+ end
43
+
44
+ def server_based?
45
+ self.class.to_s == "Rackconnect::ServerGroup"
46
+ end
47
+
48
+ end
@@ -0,0 +1,22 @@
1
+ module Rackconnect::BulkableModel
2
+
3
+ def self.included(base)
4
+ base.send :include, Rackconnect::Model
5
+ base.send :include, InstanceMethods
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module InstanceMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ def bulk_path(str)
14
+ @_bulk_endpoint = str
15
+ end
16
+
17
+ def for_server(server_id)
18
+ resp = Rackconnect::Request.get(@_bulk_endpoint + "?cloud_server_id=#{server_id}")
19
+ self.new(json: resp.body.first)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ module Rackconnect
2
+
3
+ IDENTITY_URL = "https://identity.api.rackspacecloud.com/v2.0/tokens"
4
+ RACKCONNECT_URL = "http://private-12275-rcv3.apiary-mock.com"
5
+
6
+ end
@@ -0,0 +1,72 @@
1
+ module Rackconnect::Model
2
+
3
+ def self.included(base)
4
+ base.send :include, InstanceMethods
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def initialize(options={})
10
+ if options[:json] != nil
11
+ options[:json].each do |(k,v)|
12
+ self.send("#{k}=", v)
13
+ end
14
+ end
15
+ end
16
+
17
+ def destroy
18
+ path = self.class.instance_variable_get("@_endpoint") + "/#{self.id}" # sorry
19
+ resp = Rackconnect::Request.delete(path)
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ def endpoint(str=nil, options={}, &block)
25
+ @_endpoint = block_given? ? yield(block) : str
26
+ end
27
+
28
+ def endpoint_vars(*args)
29
+ # Inject into class level of descendant class
30
+ self.class.module_eval{ attr_accessor *args }
31
+ end
32
+
33
+ def attributes(*args)
34
+ attr_accessor *args
35
+ end
36
+
37
+ def all(*args)
38
+ apply(args)
39
+ resp = Rackconnect::Request.get(@_endpoint)
40
+ resp.body.map{ |obj| self.new(json: obj) }
41
+ end
42
+
43
+ def find(*args)
44
+ id = apply(args)
45
+ resp = Rackconnect::Request.get("#{@_endpoint}/#{id}")
46
+ self.new(json: resp.body)
47
+ end
48
+
49
+ def create(options={})
50
+ resp = Rackconnect::Request.post(@_endpoint, body: options.to_json)
51
+ self.new(json: resp.body)
52
+ end
53
+
54
+ private
55
+
56
+ def apply(args)
57
+ first = args.first
58
+
59
+ # Plain resource ID string
60
+ return first if first.is_a?(String)
61
+
62
+ # Parent IDs, etc.
63
+ if first.is_a?(Array)
64
+ args.each do |(arg)|
65
+ arg.each do |(k,v)|
66
+ self.send("#{k}=", v)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,52 @@
1
+ class Rackconnect::Request
2
+
3
+ class << self
4
+
5
+ def get(path, options={})
6
+ self.new(options.merge({verb: :get, path: path}))
7
+ end
8
+
9
+ def post(path, options={})
10
+ self.new(options.merge({verb: :post, path: path}))
11
+ end
12
+
13
+ def delete(path)
14
+ self.new({verb: :delete, path: path})
15
+ true
16
+ end
17
+
18
+ end
19
+
20
+ attr_accessor :body
21
+
22
+ def initialize(options={})
23
+ verb = options[:verb]
24
+ path = options[:path]
25
+ body = options[:body]
26
+ headers = options[:headers] || {}
27
+ headers.merge({"X-Auth-Token" => Rackconnect.token})
28
+
29
+ if Rackconnect.token == nil
30
+ raise "Please authenticate first. (Rackconnect::Auth)"
31
+ elsif verb == nil || path == nil
32
+ raise "Need verb and path (Rackconnect::Request.new({verb: :get, path: \"google.com\"}))"
33
+ else
34
+ url = Rackconnect::RACKCONNECT_URL + "/v3/#{Rackconnect.tenant_id}" + path
35
+
36
+ if verb == :get
37
+ resp = RestClient.get(url)
38
+ elsif verb == :post
39
+ resp = RestClient.post(url, body, content_type: :json, accept: :json)
40
+ elsif verb == :delete
41
+ resp = RestClient.delete(url)
42
+ end
43
+
44
+ # TODO: Total hack. Bad API ATM.
45
+
46
+ unless resp.code == 204
47
+ self.body = JSON.parse(resp.gsub(/\"ACTIVE,/, '"ACTIVE",').gsub(/null"/, "null"))
48
+ end
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,19 @@
1
+ module Rackconnect::SingletonModel
2
+
3
+ def self.included(base)
4
+ base.send :include, Rackconnect::Model
5
+ base.send :include, InstanceMethods
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module InstanceMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ def all(*args)
14
+ apply(args)
15
+ resp = Rackconnect::Request.get(@_endpoint)
16
+ self.new(json: resp.body)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ class Rackconnect::CloudNetwork
2
+ include Rackconnect::Model
3
+
4
+ endpoint "/cloud_networks"
5
+ attributes :cidr, :created, :id, :name, :updated
6
+
7
+ end
@@ -0,0 +1,8 @@
1
+ class Rackconnect::LoadBalancerPool
2
+ include Rackconnect::Model
3
+ include Rackconnect::BulkNodes
4
+
5
+ endpoint "/load_balancer_pools"
6
+ attributes :id, :name, :node_counts, :port, :status, :status_detail, :virtual_ip
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Rackconnect::LoadBalancerPoolDetails
2
+ include Rackconnect::SingletonModel
3
+
4
+ endpoint_vars :pool_id, :node_id
5
+ endpoint { "/load_balancer_pools/#{pool_id}/nodes/#{node_id}/details" }
6
+ attributes :created, :cloud_server, :id, :load_balancer_pool, :status, :status_detail, :updated
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Rackconnect::LoadBalancerPoolNode
2
+ include Rackconnect::Model
3
+
4
+ endpoint_vars :pool_id
5
+ endpoint { "/load_balancer_pools/#{self.pool_id}/nodes" }
6
+ attributes :created, :cloud_server, :id, :load_balancer_pool, :status, :status_detail, :updated
7
+
8
+ end
@@ -0,0 +1,10 @@
1
+ class Rackconnect::LoadBalancerPoolNodeDetails
2
+ include Rackconnect::SingletonModel
3
+ include Rackconnect::BulkableModel
4
+
5
+ endpoint_vars :pool_id, :node_id
6
+ endpoint { "/load_balancer_pools/#{pool_id}/nodes/#{node_id}/details" }
7
+ attributes :created, :cloud_server, :id, :load_balancer_pool, :status, :status_detail, :updated
8
+ bulk_path "/load_balancer_pools/nodes/details"
9
+
10
+ end
@@ -0,0 +1,8 @@
1
+ class Rackconnect::PublicIP
2
+ include Rackconnect::BulkableModel
3
+
4
+ endpoint "/public_ips"
5
+ attributes :created, :cloud_server, :id, :public_ip_v4, :status, :status_detail, :updated
6
+ bulk_path "/public_ips"
7
+
8
+ end