fog-oneandone 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/CONTRIBUTING.md +276 -0
  4. data/CONTRIBUTORS.md +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.md +20 -0
  7. data/README.md +317 -0
  8. data/bin/fog +78 -0
  9. data/examples/example_app.rb +80 -0
  10. data/fog-oneandone.gemspec +22 -0
  11. data/gemfiles/Gemfile-edge +7 -0
  12. data/lib/fog-oneandone.rb +10 -0
  13. data/lib/oneandone/compute.rb +713 -0
  14. data/lib/oneandone/core.rb +11 -0
  15. data/lib/oneandone/models/compute/firewall.rb +128 -0
  16. data/lib/oneandone/models/compute/firewalls.rb +24 -0
  17. data/lib/oneandone/models/compute/image.rb +72 -0
  18. data/lib/oneandone/models/compute/images.rb +24 -0
  19. data/lib/oneandone/models/compute/load_balancer.rb +149 -0
  20. data/lib/oneandone/models/compute/load_balancers.rb +24 -0
  21. data/lib/oneandone/models/compute/monitoring_policies.rb +24 -0
  22. data/lib/oneandone/models/compute/monitoring_policy.rb +196 -0
  23. data/lib/oneandone/models/compute/private_network.rb +105 -0
  24. data/lib/oneandone/models/compute/private_networks.rb +24 -0
  25. data/lib/oneandone/models/compute/public_ip.rb +68 -0
  26. data/lib/oneandone/models/compute/public_ips.rb +24 -0
  27. data/lib/oneandone/models/compute/server.rb +434 -0
  28. data/lib/oneandone/models/compute/servers.rb +24 -0
  29. data/lib/oneandone/models/compute/shared_storage.rb +101 -0
  30. data/lib/oneandone/models/compute/shared_storages.rb +24 -0
  31. data/lib/oneandone/models/compute/vpn.rb +70 -0
  32. data/lib/oneandone/models/compute/vpns.rb +24 -0
  33. data/lib/oneandone/requests/compute/access.rb +35 -0
  34. data/lib/oneandone/requests/compute/add_firewall.rb +70 -0
  35. data/lib/oneandone/requests/compute/add_firewall_ips.rb +67 -0
  36. data/lib/oneandone/requests/compute/add_firewall_rules.rb +68 -0
  37. data/lib/oneandone/requests/compute/add_hdds.rb +65 -0
  38. data/lib/oneandone/requests/compute/add_load_balancer.rb +76 -0
  39. data/lib/oneandone/requests/compute/add_load_balancer_ips.rb +67 -0
  40. data/lib/oneandone/requests/compute/add_load_balancer_rules.rb +68 -0
  41. data/lib/oneandone/requests/compute/add_mp_servers.rb +64 -0
  42. data/lib/oneandone/requests/compute/add_ports.rb +65 -0
  43. data/lib/oneandone/requests/compute/add_private_network.rb +65 -0
  44. data/lib/oneandone/requests/compute/add_private_network_servers.rb +67 -0
  45. data/lib/oneandone/requests/compute/add_processes.rb +65 -0
  46. data/lib/oneandone/requests/compute/add_server_ip.rb +72 -0
  47. data/lib/oneandone/requests/compute/add_shared_storage_servers.rb +64 -0
  48. data/lib/oneandone/requests/compute/change_password.rb +45 -0
  49. data/lib/oneandone/requests/compute/change_status.rb +69 -0
  50. data/lib/oneandone/requests/compute/clone_server.rb +67 -0
  51. data/lib/oneandone/requests/compute/create_firewall.rb +78 -0
  52. data/lib/oneandone/requests/compute/create_image.rb +101 -0
  53. data/lib/oneandone/requests/compute/create_load_balancer.rb +104 -0
  54. data/lib/oneandone/requests/compute/create_monitoring_policy.rb +93 -0
  55. data/lib/oneandone/requests/compute/create_private_network.rb +82 -0
  56. data/lib/oneandone/requests/compute/create_public_ip.rb +77 -0
  57. data/lib/oneandone/requests/compute/create_server.rb +139 -0
  58. data/lib/oneandone/requests/compute/create_shared_storage.rb +83 -0
  59. data/lib/oneandone/requests/compute/create_snapshot.rb +51 -0
  60. data/lib/oneandone/requests/compute/create_vpn.rb +80 -0
  61. data/lib/oneandone/requests/compute/delete_firewall.rb +51 -0
  62. data/lib/oneandone/requests/compute/delete_firewall_rule.rb +60 -0
  63. data/lib/oneandone/requests/compute/delete_hdd.rb +61 -0
  64. data/lib/oneandone/requests/compute/delete_image.rb +51 -0
  65. data/lib/oneandone/requests/compute/delete_load_balancer.rb +51 -0
  66. data/lib/oneandone/requests/compute/delete_load_balancer_rule.rb +60 -0
  67. data/lib/oneandone/requests/compute/delete_monitoring_policy.rb +51 -0
  68. data/lib/oneandone/requests/compute/delete_port.rb +60 -0
  69. data/lib/oneandone/requests/compute/delete_private_network.rb +51 -0
  70. data/lib/oneandone/requests/compute/delete_process.rb +60 -0
  71. data/lib/oneandone/requests/compute/delete_public_ip.rb +51 -0
  72. data/lib/oneandone/requests/compute/delete_server.rb +51 -0
  73. data/lib/oneandone/requests/compute/delete_server_ip.rb +60 -0
  74. data/lib/oneandone/requests/compute/delete_shared_storage.rb +51 -0
  75. data/lib/oneandone/requests/compute/delete_snapshot.rb +51 -0
  76. data/lib/oneandone/requests/compute/delete_vpn.rb +51 -0
  77. data/lib/oneandone/requests/compute/eject_dvd.rb +51 -0
  78. data/lib/oneandone/requests/compute/get_datacenter.rb +50 -0
  79. data/lib/oneandone/requests/compute/get_dvd.rb +50 -0
  80. data/lib/oneandone/requests/compute/get_dvd_iso.rb +50 -0
  81. data/lib/oneandone/requests/compute/get_firewall.rb +50 -0
  82. data/lib/oneandone/requests/compute/get_firewall_ip.rb +59 -0
  83. data/lib/oneandone/requests/compute/get_firewall_rule.rb +59 -0
  84. data/lib/oneandone/requests/compute/get_fixed_server.rb +50 -0
  85. data/lib/oneandone/requests/compute/get_hardware.rb +50 -0
  86. data/lib/oneandone/requests/compute/get_hdd.rb +60 -0
  87. data/lib/oneandone/requests/compute/get_hdds.rb +50 -0
  88. data/lib/oneandone/requests/compute/get_image.rb +50 -0
  89. data/lib/oneandone/requests/compute/get_load_balancer.rb +50 -0
  90. data/lib/oneandone/requests/compute/get_load_balancer_ip.rb +59 -0
  91. data/lib/oneandone/requests/compute/get_load_balancer_rule.rb +59 -0
  92. data/lib/oneandone/requests/compute/get_log.rb +51 -0
  93. data/lib/oneandone/requests/compute/get_monitored_server.rb +49 -0
  94. data/lib/oneandone/requests/compute/get_monitoring_policy.rb +50 -0
  95. data/lib/oneandone/requests/compute/get_mp_server.rb +59 -0
  96. data/lib/oneandone/requests/compute/get_port.rb +59 -0
  97. data/lib/oneandone/requests/compute/get_private_network.rb +50 -0
  98. data/lib/oneandone/requests/compute/get_private_network_server.rb +59 -0
  99. data/lib/oneandone/requests/compute/get_process.rb +59 -0
  100. data/lib/oneandone/requests/compute/get_public_ip.rb +50 -0
  101. data/lib/oneandone/requests/compute/get_server.rb +50 -0
  102. data/lib/oneandone/requests/compute/get_server_appliance.rb +50 -0
  103. data/lib/oneandone/requests/compute/get_server_image.rb +50 -0
  104. data/lib/oneandone/requests/compute/get_server_ip.rb +59 -0
  105. data/lib/oneandone/requests/compute/get_server_private_network.rb +59 -0
  106. data/lib/oneandone/requests/compute/get_shared_storage.rb +50 -0
  107. data/lib/oneandone/requests/compute/get_shared_storage_server.rb +59 -0
  108. data/lib/oneandone/requests/compute/get_snapshot.rb +50 -0
  109. data/lib/oneandone/requests/compute/get_vpn.rb +50 -0
  110. data/lib/oneandone/requests/compute/install_server_image.rb +72 -0
  111. data/lib/oneandone/requests/compute/list_datacenters.rb +56 -0
  112. data/lib/oneandone/requests/compute/list_dvds.rb +56 -0
  113. data/lib/oneandone/requests/compute/list_firewall_ips.rb +50 -0
  114. data/lib/oneandone/requests/compute/list_firewall_rules.rb +50 -0
  115. data/lib/oneandone/requests/compute/list_firewalls.rb +56 -0
  116. data/lib/oneandone/requests/compute/list_fixed_servers.rb +40 -0
  117. data/lib/oneandone/requests/compute/list_images.rb +56 -0
  118. data/lib/oneandone/requests/compute/list_ip_firewalls.rb +59 -0
  119. data/lib/oneandone/requests/compute/list_ip_load_balancers.rb +59 -0
  120. data/lib/oneandone/requests/compute/list_load_balancer_ips.rb +50 -0
  121. data/lib/oneandone/requests/compute/list_load_balancer_rules.rb +50 -0
  122. data/lib/oneandone/requests/compute/list_load_balancers.rb +56 -0
  123. data/lib/oneandone/requests/compute/list_logs.rb +59 -0
  124. data/lib/oneandone/requests/compute/list_monitored_servers.rb +51 -0
  125. data/lib/oneandone/requests/compute/list_monitoring_policies.rb +56 -0
  126. data/lib/oneandone/requests/compute/list_mp_servers.rb +50 -0
  127. data/lib/oneandone/requests/compute/list_ports.rb +51 -0
  128. data/lib/oneandone/requests/compute/list_private_network_servers.rb +50 -0
  129. data/lib/oneandone/requests/compute/list_private_networks.rb +56 -0
  130. data/lib/oneandone/requests/compute/list_processes.rb +51 -0
  131. data/lib/oneandone/requests/compute/list_public_ips.rb +56 -0
  132. data/lib/oneandone/requests/compute/list_server_appliances.rb +56 -0
  133. data/lib/oneandone/requests/compute/list_server_ips.rb +50 -0
  134. data/lib/oneandone/requests/compute/list_server_private_networks.rb +50 -0
  135. data/lib/oneandone/requests/compute/list_servers.rb +56 -0
  136. data/lib/oneandone/requests/compute/list_shared_storage_servers.rb +50 -0
  137. data/lib/oneandone/requests/compute/list_shared_storages.rb +56 -0
  138. data/lib/oneandone/requests/compute/list_usages.rb +54 -0
  139. data/lib/oneandone/requests/compute/list_vpns.rb +56 -0
  140. data/lib/oneandone/requests/compute/load_dvd.rb +65 -0
  141. data/lib/oneandone/requests/compute/ping.rb +38 -0
  142. data/lib/oneandone/requests/compute/ping_auth.rb +38 -0
  143. data/lib/oneandone/requests/compute/remove_firewall.rb +60 -0
  144. data/lib/oneandone/requests/compute/remove_firewall_ip.rb +60 -0
  145. data/lib/oneandone/requests/compute/remove_load_balancer.rb +71 -0
  146. data/lib/oneandone/requests/compute/remove_load_balancer_ip.rb +60 -0
  147. data/lib/oneandone/requests/compute/remove_mp_server.rb +60 -0
  148. data/lib/oneandone/requests/compute/remove_private_network.rb +60 -0
  149. data/lib/oneandone/requests/compute/remove_private_network_server.rb +60 -0
  150. data/lib/oneandone/requests/compute/remove_shared_storage_server.rb +60 -0
  151. data/lib/oneandone/requests/compute/restore_snapshot.rb +35 -0
  152. data/lib/oneandone/requests/compute/status.rb +50 -0
  153. data/lib/oneandone/requests/compute/update_firewall.rb +76 -0
  154. data/lib/oneandone/requests/compute/update_hardware.rb +82 -0
  155. data/lib/oneandone/requests/compute/update_hdd.rb +71 -0
  156. data/lib/oneandone/requests/compute/update_image.rb +80 -0
  157. data/lib/oneandone/requests/compute/update_load_balancer.rb +96 -0
  158. data/lib/oneandone/requests/compute/update_monitoring_policy.rb +82 -0
  159. data/lib/oneandone/requests/compute/update_port.rb +74 -0
  160. data/lib/oneandone/requests/compute/update_private_network.rb +82 -0
  161. data/lib/oneandone/requests/compute/update_process.rb +76 -0
  162. data/lib/oneandone/requests/compute/update_public_ip.rb +71 -0
  163. data/lib/oneandone/requests/compute/update_server.rb +76 -0
  164. data/lib/oneandone/requests/compute/update_shared_storage.rb +80 -0
  165. data/lib/oneandone/requests/compute/update_vpn.rb +76 -0
  166. data/tests/oneandone/test_firewalls.rb +188 -0
  167. data/tests/oneandone/test_images.rb +79 -0
  168. data/tests/oneandone/test_load_balancers.rb +192 -0
  169. data/tests/oneandone/test_monitoring_policies.rb +342 -0
  170. data/tests/oneandone/test_private_networks.rb +123 -0
  171. data/tests/oneandone/test_public_ips.rb +75 -0
  172. data/tests/oneandone/test_servers.rb +465 -0
  173. data/tests/oneandone/test_shared_storages.rb +131 -0
  174. metadata +259 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 56d7c39794b25233e7aaa863d457f412a671af87
4
+ data.tar.gz: b2c478a22092ab58ad2ba8981cd28b317d83a611
5
+ SHA512:
6
+ metadata.gz: a067ef076c2893ded4479444789baf5fd6cf9cd768d9d772a2f30e91c392c4d1e6c90a84c5544d62288e5b15d5e58db0638dbebd37c05eb1d3bb3482c2535dd1
7
+ data.tar.gz: 959e2eda82a1a0e56550fff4ad9020eb016c002c3e80af37cfef55db86e085e1b1bc870f27f6080bb52ddecfe280e7c4c28ddc05f1697a000f123d1b611ca344
data/.gitignore ADDED
@@ -0,0 +1,36 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ ## Specific to RubyMotion:
14
+ .dat*
15
+ .repl_history
16
+ build/
17
+
18
+ ## Documentation cache and generated files:
19
+ /.yardoc/
20
+ /_yardoc/
21
+ /doc/
22
+ /rdoc/
23
+
24
+ ## Environment normalization:
25
+ /.bundle/
26
+ /vendor/bundle
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ # Gemfile.lock
32
+ # .ruby-version
33
+ # .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,276 @@
1
+ # Getting Involved
2
+
3
+ ## Introduction
4
+
5
+ First off, high five for coming to visit this page. You are my new hero.
6
+
7
+ New contributors are always welcome, when it doubt please ask questions. We strive to be an open and welcoming community. Please be nice to one another.
8
+
9
+ ### Coding
10
+
11
+ * Pick a task:
12
+ * Offer feedback on open [pull requests](https://github.com/fog/fog/pulls).
13
+ * Review open [issues](https://github.com/fog/fog/issues) for things to help on.
14
+ * [Create an issue](https://github.com/fog/fog/issues/new) to start a discussion on additions or features.
15
+ * Fork the project, add your changes and tests to cover them in a topic branch.
16
+ * Commit your changes and rebase against `fog/fog` to ensure everything is up to date.
17
+ * [Submit a pull request](https://github.com/fog/fog/compare/)
18
+
19
+ ### Non-Coding
20
+
21
+ * Offer feedback on open [issues](https://github.com/fog/fog/issues).
22
+ * Write and help edit [documentation](https://github.com/fog/fog.github.com).
23
+ * Translate [documentation](https://github.com/fog/fog.github.com) in to other languages.
24
+ * Organize or volunteer at events.
25
+ * [Donate](https://www.gittip.com/geemus/)
26
+ * Discuss other ideas for contribution with [geemus](mailto:geemus+fog@gmail.com).
27
+
28
+ ### Changes
29
+
30
+ Before we go into more detail, please be aware that Fog is going through some growing pains right now. A lot of things are moving right now, and things may not be documented as well as we would like.
31
+
32
+ It might be wise to check out the [Roadmap](https://github.com/fog/fog/wiki/Roadmap) and [Design Document](https://github.com/fog/fog/wiki/fog-design-document) in the Wiki for more information.
33
+
34
+ For right now, there are three major things in motion:
35
+
36
+ #### Meta-gem movement
37
+
38
+ Fog is moving from a monolithic gem structure to a meta-gem structure, where code for specific providers will be housed in `fog-provider` gems. Extracting provider code is an ongoing process, and is also causing some performance issues.
39
+
40
+ Relevant issues include:
41
+
42
+ - General: [#1253](https://github.com/fog/fog/issues/1253), [#2602](https://github.com/fog/fog/issues/2602), [#2681](https://github.com/fog/fog/issues/2681), [#2877](https://github.com/fog/fog/issues/2877)
43
+ - Performance: [#3430](https://github.com/fog/fog/issues/3430)
44
+
45
+ #### Testing
46
+
47
+ In the past, fog has used the [Shindo](https://github.com/geemus/shindo) test framework, but is moving toward using `minitest` instead. Furthermore, the mocking structure fog has used to test in the past is undergoing some scrutiny and changes.
48
+
49
+ Relevant issues include:
50
+
51
+ - General: [#1266](https://github.com/fog/fog/issues/1266)
52
+ - Shindo -> minitest: [#2630](https://github.com/fog/fog/issues/2630)
53
+ - Mocking: [#1252](https://github.com/fog/fog/issues/1252), [#1266](https://github.com/fog/fog/issues/1266) starting about halfway down, [#1418](https://github.com/fog/fog/issues/1418), [#2629](https://github.com/fog/fog/issues/2629)
54
+
55
+ ## Overview
56
+
57
+ * Organize your patches by keeping all related changes together in a topic branch.
58
+ * Rebase your branch against master before submitting a pull request (and squish any 'oops' or work in progress commits).
59
+ * We support several rubies! Make sure your changes will work for all the Rubies in `.travis.yml`
60
+ * Submit changes as pull requests describing what the changes should cover and referencing issues (if any).
61
+ * Use 'tags' in your commits to indicate the scope, so things like `[aws|compute] fixed something`.
62
+ * Write and run tests. Tests should follow through usage workflows and ought to pass both with mocking on and off.
63
+
64
+ ## Deep dive
65
+
66
+ Now then, some of the what makes it tick and why. For simplicity let's pretend you want to implement a new service, from scratch. I will walk through the requisite pieces and important things to keep in mind as you go.
67
+
68
+ But, before I dive too deep, I'll leave you with an out. Other great ways to contribute are fixing bugs, writing documentation or helping port other projects to use fog. That way everybody wins!
69
+
70
+ ## The Service
71
+
72
+ First and foremost you'll need to create a service, which should start from something like:
73
+
74
+ module Fog
75
+ class TheService < Fog::Service
76
+
77
+ requires :necessary_credential
78
+
79
+ model_path 'path/to/models'
80
+ collection 'name_of_collection'
81
+ model 'name_of_model'
82
+
83
+ request_path 'path/to/requests'
84
+ request 'name_of_request'
85
+
86
+ class Mock
87
+ include Collections
88
+ end
89
+
90
+ class Real
91
+ include Collections
92
+ end
93
+
94
+ end
95
+ end
96
+
97
+ ### Highlights:
98
+ * we segregate between real and mock so it is easier to add stuff to one or the other later.
99
+ * this is where any shared stuff will go, like making/signing requests
100
+
101
+ ## Requests
102
+
103
+ The next thing to bite off are the requests. fog is all about making cloud services easier to use and move between, but requests are not where this happens. Requests should map closely to the actual api requests (you should be able to directly reference the api docs and vice versa). In particular, try to keep the output of any data parsing as close to the actual format as possible. This makes implementation and maintenance much easier and provides a solid foundation for models to build nice things on top of. I generally end up working on stuff to get/list details first and then filling in create/destroy pairs and other requests.
104
+ You start with something like this:
105
+
106
+ <pre>
107
+ module Fog
108
+ class TheService
109
+
110
+ class Real
111
+
112
+ def request(*args)
113
+ end
114
+
115
+ end
116
+
117
+ class Mock
118
+
119
+ def request(*args)
120
+ Fog::Mock.not_implemented
121
+ end
122
+
123
+ end
124
+
125
+ end
126
+ end
127
+ </pre>
128
+
129
+ ### Highlights:
130
+ * You should define the method twice, once for the real implementation and once for mocked (they should take the same arguments).
131
+ * The mock versions should just start out by raising a not implemented error, you can come back and fill this in later.
132
+ * The real version should make a request, probably by a method defined on the real class in the service you defined earlier.
133
+ * Each request should either return an Excon::Response (with a parsed body where appropriate) or raise an error.
134
+
135
+ ## Tests
136
+
137
+ Now would be a good time to write some tests to make sure what you have written works (and will continue to). I've tried a couple variations on testing in the past, but have settled on consolidated lifetime testing. These vary enough that its hard to give a single simple example, but you can see many examples in [tests/aws/requests/compute](https://github.com/fog/fog/tree/master/tests/aws/requests/compute).
138
+
139
+ ### Highlights:
140
+ * Reuse the same objects and take them through their whole life cycle (this is much faster, and most of the time if one portion fails the others would anyway).
141
+ * Test the format of the output to ensure parsers match expectations (check the provider's api docs) and that mocks return matching data.
142
+ * Test common failure cases and their behavior, you'll need to know how the service acts in these cases to make better mocks.
143
+
144
+ ## Models
145
+
146
+ You could also skip to the mocks here if you wanted, but I usually find the more time I spend working with the service the easier it is to build mocks. The models are the real pay dirt, you have slogged through low level requests that map to the provider api and now you want a nice interface. This is where models and collections come in. Collections provide access to lists of data on the provider and for creating new objects. Models represent the individual objects.
147
+
148
+ If you know which object you'd like to represent you should start with the collection. When naming, please refer to the names that have been chosen for other services. I haven't standardized all nouns yet, but a few are already shared (Flavor, Image, Server)
149
+ An example servers collection:
150
+
151
+ require 'fog/collection'
152
+ require 'fog/theservice/models/server'
153
+ module Fog
154
+ class TheService
155
+
156
+ class Servers < Fog::Collection
157
+
158
+ model Fog::TheService::Server
159
+
160
+ def all
161
+ # get list of servers
162
+ load(data) # data is an array of attribute hashes
163
+ end
164
+
165
+ def get(identity)
166
+ # get server matching id
167
+ new(data) # data is an attribute hash
168
+ rescue Excon::Errors::NotFound
169
+ nil
170
+ end
171
+
172
+ end
173
+
174
+ end
175
+ end
176
+
177
+ ### Highlights
178
+ * First make an accessor in the Collections model so it will be included in Real and Mock.
179
+ * `#model` will take a reference to the class that will be instantiated to represent individual objects.
180
+ * `#all` should get a list of servers from the provider and pass an array of attribute hashes, one per server, to load.
181
+ * `#get` should take an identity reference and instantiate a new model object with an attribute hash returned from the remote server, or return nil of no such object exists.
182
+
183
+ Models handle remapping attributes into friendlier names and providing the rest of the interface.
184
+ An example model:
185
+
186
+ require 'fog/model'
187
+ module Fog
188
+ module TheService
189
+
190
+ class Server << Fog::Model
191
+
192
+ identity :id
193
+
194
+ attribute :state, 'StatusValue'
195
+
196
+ def destroy
197
+ requires :identity
198
+ connection.destroy_server(identity)
199
+ true
200
+ end
201
+
202
+ def ready?
203
+ state == 'running'
204
+ end
205
+
206
+ def save
207
+ requires ...
208
+ connection.create_server(options)
209
+ true
210
+ end
211
+
212
+ end
213
+
214
+ end
215
+ end
216
+
217
+ ### Highlights
218
+ * `#identity` captures the id/name that the objects are identified by and takes the same arguments as attribute.
219
+ * `#attribute` takes the name to make a variable available as and one or more aliases that parsers/requests will return this value as.
220
+ * `#destroy` will require the identity of the model and should destroy it and return true.
221
+ * `#ready?` should return whether the object has finished being initialized (where appropriate).
222
+ * `#save` should take any required objects and instantiate the object on the provider's service.
223
+ * These models just rely on underlying collections and requests, so it should not be necessary at this level to distinguish between Real and Mock methods.
224
+
225
+ ## Mocks
226
+
227
+ Mocks provide a powerful tool for users of fog to experiment with their implementations much more quickly and without incurring costs. I usually save these for last, as implementing the requests and models provide some necessary context to finally put the mocks together. Your services mock class should have a data method that will return mocked data like so:
228
+
229
+ module Fog
230
+ module TheService
231
+
232
+ class Mock
233
+ def self.data
234
+ @data ||= Hash.new do |hash, key|
235
+ hash[key] = {}
236
+ end
237
+ end
238
+ end
239
+
240
+ end
241
+ end
242
+
243
+ The keys in this hash should represent a unique identifier of the user accessing the data and the value assigned should contain any default data that a new user might have. Any implemented mock requests should then return data retrieved from here or raise an error.
244
+ For instance:
245
+
246
+ module Fog
247
+ module TheService
248
+
249
+ class Mock
250
+
251
+ def destroy_server(server_identity)
252
+ if data = self.data[:servers].delete(server_identity)
253
+ response = Excon::Response.new
254
+ response.status = 202
255
+ response.body = data
256
+ response
257
+ else
258
+ raise Fog::TheService::NotFound
259
+ end
260
+ end
261
+
262
+ end
263
+
264
+ end
265
+ end
266
+
267
+ ### Highlights
268
+ * Mock requests should return the same type of data as an already parsed real response or should return the same error as a real problem.
269
+ * By mocking at this low level, higher level functions are automatically mocked out for you.
270
+ * The extra rigorous tests related to output formatting and error messages should help keep you honest, and each should pass in both mocked and unmocked modes.
271
+
272
+ ## Summary
273
+
274
+ That provides a lot more detail than you will probably need right away, but hopefully you can refer back to different sections as you need them. If you have any questions send me a github message or email me (address is on my profile). You should always start development by creating your own fork. When you feel confident about your fork, send me a pull request. Be forewarned that I may edit some things before it gets to master, but I'll do my best to take care of this in a timely manner.
275
+
276
+ Thanks again for your interest and let me know if there is anything else I can do to help.
data/CONTRIBUTORS.md ADDED
@@ -0,0 +1 @@
1
+ * Tyler Burkhardt <tyler@stackpointcloud.com>
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fog-oneandone.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2009-2015 [CONTRIBUTORS.md](https://github.com/fog/fog/blob/master/CONTRIBUTORS.md)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,317 @@
1
+ # Fog-oneandone
2
+
3
+ [![Build Status](https://travis-ci.org/tjb1019/fog.svg?branch=master)](https://travis-ci.org/tjb1019/fog)
4
+
5
+ Fog is an open-source, community Ruby library used for interacting with popular cloud infrastructure providers through a single, unified API.
6
+
7
+ This guide will show you how to programmatically use the 1&amp;1 provider in Fog to perform common management tasks available in the 1&amp;1 Cloud Panel.
8
+
9
+ ## Table of Contents
10
+
11
+ - [Overview](#overview)
12
+ - [Getting Started](#getting-started)
13
+ * [Installation](#installation)
14
+ * [Authentication](#authentication)
15
+ - [Models](#models)
16
+ - [Creating a Server](#creating-a-server)
17
+ - [Updating Server Cores, Memory, and Disk](#updating-server-cores-memory-and-disk)
18
+ - [Deleting a Server](#deleting-a-server)
19
+ - [Collections](#collections)
20
+ - [Mocks](#mocks)
21
+ - [Example App](#example-app)
22
+
23
+
24
+
25
+ ## Overview
26
+
27
+ The Fog library wraps the <a href='https://cloudpanel-api.1and1.com/documentation/1and1/v1/en/documentation.html'>1&amp;1 REST API</a>. All API operations are performed over SSL and authenticated using your 1&amp;1 credentials. The API can be accessed within an instance running in 1&amp;1 or directly over the Internet from any application that can send an HTTPS request and receive an HTTPS response.
28
+
29
+ The Fog library provides two methods of interacting with 1&amp;1. The first method utilizes an abstracted collection and model layer that is similar across all cloud providers within Fog.
30
+
31
+ A collection is a group of similar resources such as servers, images, or firewalls and allows basic CRUD (create/read/update/delete) operations on collections and models. This guide will cover interactions with the 1&amp;1 environment solely using collections and models.
32
+
33
+ While out of scope of this guide, the second Fog method provides direct request methods that specifically match provider API methods. In the case of the 1&amp;1 provider, the request methods map to the <a href='https://cloudpanel-api.1and1.com/documentation/1and1/v1/en/documentation.html'>1&amp;1 REST API</a> endpoints and parameters. More details on requests can be found at the <a href='http://fog.io'>Fog</a> website.
34
+
35
+
36
+ ## Getting Started
37
+
38
+ Before you begin you will need to have signed-up for a 1&amp;1 account. The credentials you setup during sign-up will be used to authenticate against the API.
39
+
40
+
41
+ ### Installation
42
+
43
+ You can install the latest stable version using:
44
+
45
+ `$ gem install fog-oneandone`
46
+
47
+
48
+ ### Authentication
49
+
50
+ Connecting to 1&amp;1 can be done by creating a compute connection with the provider.
51
+
52
+ ```ruby
53
+ require 'fog-oneandone'
54
+
55
+ compute = Fog::Compute::OneAndOne.new({
56
+ :oneandone_api_key => '<API-TOKEN>'
57
+ })
58
+ ```
59
+
60
+ Credentials can be specified as shown above or placed in a `.fog` file located in the home directory.
61
+
62
+ ```bash
63
+ $ less ~/.fog
64
+ default:
65
+ oneandone_api_key: <API-TOKEN>
66
+ ```
67
+
68
+
69
+ ## Models
70
+
71
+ Models act as your interface for working with provider resources. In the examples below, we will create a server, and perform various actions to that server using its model. All models come equipped with the `wait_for` and `destroy` methods, as well as other methods that perform various `POST`, `PUT`, and `DELETE` actions. These additional methods vary by model.
72
+
73
+
74
+ ### Creating a Server
75
+
76
+ The following example shows you how to create a new server in the Great Britain
77
+ data center with a fixed hardware configuration.
78
+
79
+ The server can take time to provision. The `wait_for` server object method will wait until the server state is available before continuing, and returns a hash containing the method's execution duration. This is useful when chaining together requests that are dependent upon one another.
80
+
81
+ A server "model" will be returned to the `my_server` variable. You can use this model to access the server's attributes and perform further operations.
82
+ ```ruby
83
+ compute = Fog::Compute::OneAndOne.new({
84
+ :oneandone_api_key => '<API-TOKEN>'
85
+ })
86
+
87
+
88
+ my_server = compute.servers.create(name: 'My Server',
89
+ fixed_instance_id: '65929629F35BBFBA63022008F773F3EB',
90
+ appliance_id: '6C902E5899CC6F7ED18595EBEB542EE1',
91
+ datacenter_id: '5091F6D8CBFEF9C26ACE957C652D5D49')
92
+
93
+ puts my_server.wait_for { ready? }
94
+ ```
95
+
96
+ If you would prefer to set your own custom hardware configuration, then simply replace `fixed_instance_id` with values for
97
+ `vcore`, `ram`, `cores_per_processor`, and `hdds`, like so:
98
+
99
+ ```ruby
100
+ hdd1 = {
101
+ 'is_main' => true,
102
+ 'size' => 60
103
+ }
104
+
105
+ hdds = [hdd1]
106
+
107
+ my_server = compute.servers.create(name: 'My Server',
108
+ vcore: 1, ram: 1, cores_per_processor: 1, hdds: hdds
109
+ appliance_id: '6C902E5899CC6F7ED18595EBEB542EE1',
110
+ datacenter_id: '5091F6D8CBFEF9C26ACE957C652D5D49')
111
+
112
+ puts my_server.wait_for { ready? }
113
+ ```
114
+
115
+ ### Updating Server Cores, Memory, and Disk
116
+
117
+ Using our `my_server` model from above, we can easily update the server's hardware configuration, like so:
118
+
119
+ ```ruby
120
+ my_server.update_hardware(vcore: 2, ram: 4)
121
+ my_server.wait_for { ready? }
122
+
123
+ puts my_server.hardware['vcore']
124
+ >> 2
125
+
126
+ puts my_server.hardware['ram']
127
+ >> 4
128
+ ```
129
+
130
+ Need extra storage? Adding an additional HDD is easy:
131
+
132
+ ```ruby
133
+ hdd2 = {
134
+ 'is_main' => false,
135
+ 'size' => 80
136
+ }
137
+
138
+ hdds = [hdd2]
139
+
140
+ my_server.add_hdds(hdds: hdds)
141
+ my_server.wait_for { ready? }
142
+
143
+ puts my_server.hardware['hdds']
144
+ >> [{'is_main' => true, 'size' => 60}, {'is_main' => false, 'size' => 80}]
145
+ ```
146
+
147
+ Ready to downsize? Deleting storage is easy too:
148
+
149
+ ```ruby
150
+ hdd2_id = my_server.hardware['hdds'][1]['id']
151
+
152
+ my_server.delete_hdd(hdd_id: hdd2_id)
153
+ my_server.wait_for { ready? }
154
+
155
+ puts my_server.hardware['hdds']
156
+ >> [{'is_main' => true, 'size' => 60}]
157
+ ```
158
+
159
+
160
+ ### Deleting a Server
161
+
162
+ When you are finished with your server, use the `destroy` method to permanently delete the resource from the provider. The `destroy` method is available on all models.
163
+
164
+ ```ruby
165
+ puts my_server.destroy
166
+ >> true
167
+ ```
168
+
169
+
170
+ ## Collections
171
+
172
+ A high level interface to each cloud is provided through collections, such as `images` and `servers`. You can see a list of available collections by calling `collections` on the connection object.
173
+
174
+ ```ruby
175
+ compute = Fog::Compute::OneAndOne.new({
176
+ :oneandone_api_key => '<API-TOKEN>'
177
+ })
178
+
179
+ puts compute.collections
180
+ >>
181
+ servers
182
+ images
183
+ shared_storages
184
+ firewalls
185
+ load_balancers
186
+ public_ips
187
+ private_networks
188
+ monitoring_policies
189
+ vpns
190
+ ```
191
+
192
+ Each collection comes equipped with the `create`, `all`, and `get` methods. You've seen how the `create` method works in our server example above. `all` will fetch every object of that type from the provider, and generate a model for each of those objects. Here's an example:
193
+
194
+ ```ruby
195
+ servers = compute.servers.all
196
+ first_server = servers[0]
197
+
198
+ puts first_server.name
199
+ >> Test Server
200
+
201
+ puts first_server.status['state']
202
+ >> POWERED_ON
203
+
204
+ puts first_server.destroy
205
+ >> true
206
+ ```
207
+
208
+ `get` will fetch a single object from the provider and generate a model for the specified object.
209
+
210
+ ```ruby
211
+ bad_server = compute.servers.get('<BAD-SERVER-ID>')
212
+
213
+ puts bad_server.destroy
214
+ >> true
215
+ ```
216
+
217
+
218
+ ## Mocks
219
+
220
+ As you might imagine, testing code using Fog can be slow and expensive, constantly turning on and shutting down instances. Mocking allows skipping this overhead by providing an in memory representation of resources as you make requests. Enabling mocking is easy to use: before you run other commands, simply run:
221
+
222
+ ```ruby
223
+ Fog.mock!
224
+ ```
225
+
226
+ Then, proceed as usual. If you run into unimplemented mocks, fog will raise an error.
227
+
228
+
229
+
230
+ ## Example App
231
+
232
+ This simple app creates a load balancer, firewall policy, and server. It then adds the load balancer and firewall policy to the server's initial IP address. You can access a server's initial IP by using the `ips` attribute on the server model, as seen in the example below.
233
+
234
+ The source code for the Example App can be found <a href='examples/example_app.rb'>here</a>.
235
+
236
+ ```ruby
237
+ require 'fog-oneandone'
238
+
239
+ compute = Fog::Compute::OneAndOne.new({
240
+ :oneandone_api_key => '<API-TOKEN>'
241
+ })
242
+
243
+ # Create Server
244
+ my_server = compute.servers.create(name: 'Example App Server',
245
+ fixed_instance_id: '65929629F35BBFBA63022008F773F3EB',
246
+ appliance_id: '6C902E5899CC6F7ED18595EBEB542EE1',
247
+ datacenter_id: '5091F6D8CBFEF9C26ACE957C652D5D49')
248
+
249
+ puts 'Creating server...'
250
+ puts my_server.wait_for { ready? }
251
+
252
+
253
+ # Create Firewall
254
+ puts "----------"
255
+ rule1 = {
256
+ 'protocol' => 'TCP',
257
+ 'port_from' => 80,
258
+ 'port_to' => 80,
259
+ 'source' => '0.0.0.0'
260
+ }
261
+
262
+ rules = [rule1]
263
+
264
+ my_firewall = compute.firewalls.create(name: 'Example App Firewall',
265
+ rules: rules)
266
+ puts 'Creating Firewall...'
267
+ puts my_firewall.wait_for { ready? }
268
+
269
+
270
+ # Create Load Balancer
271
+ puts "----------"
272
+ rule1 = {
273
+ 'protocol' => 'TCP',
274
+ 'port_balancer' => 80,
275
+ 'port_server' => 80,
276
+ 'source' => '0.0.0.0'
277
+ }
278
+
279
+ rules = [rule1]
280
+
281
+ my_load_balancer = compute.load_balancers.create(name: 'Example App LB',
282
+ rules: rules, health_check_test: 'TCP', health_check_interval: 40,
283
+ persistence: true, persistence_time: 1200, method: 'ROUND_ROBIN',
284
+ datacenter_id: '5091F6D8CBFEF9C26ACE957C652D5D49')
285
+ puts 'Creating Load Balancer...'
286
+ puts my_load_balancer.wait_for { ready? }
287
+
288
+
289
+ # Add Firewall to Server
290
+ puts "----------"
291
+ puts 'Adding Firewall to server IP...'
292
+ my_server.add_firewall(ip_id: my_server.ips[0]['id'],
293
+ firewall_id: my_firewall.id)
294
+ puts my_server.wait_for { ready? }
295
+
296
+
297
+ # Add LB to Server
298
+ puts "----------"
299
+ puts 'Adding Load Balancer to server IP...'
300
+ my_server.add_load_balancer(ip_id: my_server.ips[0]['id'],
301
+ load_balancer_id: my_load_balancer.id)
302
+ puts my_server.wait_for { ready? }
303
+
304
+
305
+ # Cleanup
306
+ puts "----------"
307
+ puts 'Destroying server...'
308
+ puts my_server.destroy
309
+
310
+ puts "----------"
311
+ puts 'Destroying load balancer...'
312
+ puts my_load_balancer.destroy
313
+
314
+ puts "----------"
315
+ puts 'Destroying firewall...'
316
+ puts my_firewall.destroy
317
+ ```