1and1 1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/1and1-1.0.gem +0 -0
- data/1and1.gemspec +20 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +499 -0
- data/docs/reference.md +2447 -0
- data/examples/dvd_examples.rb +15 -0
- data/examples/example_app.rb +100 -0
- data/examples/firewall_examples.rb +137 -0
- data/examples/image_examples.rb +48 -0
- data/examples/load_balancer_examples.rb +145 -0
- data/examples/log_examples.rb +15 -0
- data/examples/monitoring_center_examples.rb +15 -0
- data/examples/monitoring_policy_examples.rb +343 -0
- data/examples/private_network_examples.rb +86 -0
- data/examples/public_ip_examples.rb +42 -0
- data/examples/role_examples.rb +113 -0
- data/examples/server_appliance_examples.rb +15 -0
- data/examples/server_examples.rb +438 -0
- data/examples/shared_storage_examples.rb +108 -0
- data/examples/usage_examples.rb +6 -0
- data/examples/user_examples.rb +113 -0
- data/examples/vpn_examples.rb +56 -0
- data/lib/1and1/datacenter.rb +73 -0
- data/lib/1and1/dvd.rb +73 -0
- data/lib/1and1/firewall.rb +427 -0
- data/lib/1and1/image.rb +231 -0
- data/lib/1and1/load_balancer.rb +448 -0
- data/lib/1and1/log.rb +77 -0
- data/lib/1and1/monitoring_center.rb +84 -0
- data/lib/1and1/monitoring_policy.rb +598 -0
- data/lib/1and1/oneandone.rb +57 -0
- data/lib/1and1/ping.rb +41 -0
- data/lib/1and1/ping_auth.rb +41 -0
- data/lib/1and1/pricing.rb +41 -0
- data/lib/1and1/private_network.rb +333 -0
- data/lib/1and1/public_ip.rb +192 -0
- data/lib/1and1/role.rb +381 -0
- data/lib/1and1/server.rb +1208 -0
- data/lib/1and1/server_appliance.rb +73 -0
- data/lib/1and1/shared_storage.rb +379 -0
- data/lib/1and1/usage.rb +58 -0
- data/lib/1and1/user.rb +374 -0
- data/lib/1and1/vpn.rb +249 -0
- data/lib/oneandone.rb +27 -0
- data/sphinx/Makefile +192 -0
- data/sphinx/_build/doctrees/dvds.doctree +0 -0
- data/sphinx/_build/doctrees/environment.pickle +0 -0
- data/sphinx/_build/doctrees/firewalls.doctree +0 -0
- data/sphinx/_build/doctrees/images.doctree +0 -0
- data/sphinx/_build/doctrees/index.doctree +0 -0
- data/sphinx/_build/doctrees/load_balancers.doctree +0 -0
- data/sphinx/_build/doctrees/logs.doctree +0 -0
- data/sphinx/_build/doctrees/monitoring_center.doctree +0 -0
- data/sphinx/_build/doctrees/monitoring_policies.doctree +0 -0
- data/sphinx/_build/doctrees/private_networks.doctree +0 -0
- data/sphinx/_build/doctrees/public_ips.doctree +0 -0
- data/sphinx/_build/doctrees/server_appliances.doctree +0 -0
- data/sphinx/_build/doctrees/servers.doctree +0 -0
- data/sphinx/_build/doctrees/shared_storages.doctree +0 -0
- data/sphinx/_build/doctrees/usages.doctree +0 -0
- data/sphinx/_build/doctrees/users.doctree +0 -0
- data/sphinx/_build/html/.buildinfo +4 -0
- data/sphinx/_build/html/_sources/dvds.txt +42 -0
- data/sphinx/_build/html/_sources/firewalls.txt +189 -0
- data/sphinx/_build/html/_sources/images.txt +101 -0
- data/sphinx/_build/html/_sources/index.txt +499 -0
- data/sphinx/_build/html/_sources/load_balancers.txt +231 -0
- data/sphinx/_build/html/_sources/logs.txt +55 -0
- data/sphinx/_build/html/_sources/monitoring_center.txt +55 -0
- data/sphinx/_build/html/_sources/monitoring_policies.txt +288 -0
- data/sphinx/_build/html/_sources/private_networks.txt +146 -0
- data/sphinx/_build/html/_sources/public_ips.txt +78 -0
- data/sphinx/_build/html/_sources/server_appliances.txt +42 -0
- data/sphinx/_build/html/_sources/servers.txt +630 -0
- data/sphinx/_build/html/_sources/shared_storages.txt +160 -0
- data/sphinx/_build/html/_sources/usages.txt +45 -0
- data/sphinx/_build/html/_sources/users.txt +172 -0
- data/sphinx/_build/html/_static/ajax-loader.gif +0 -0
- data/sphinx/_build/html/_static/alabaster.css +585 -0
- data/sphinx/_build/html/_static/basic.css +599 -0
- data/sphinx/_build/html/_static/comment-bright.png +0 -0
- data/sphinx/_build/html/_static/comment-close.png +0 -0
- data/sphinx/_build/html/_static/comment.png +0 -0
- data/sphinx/_build/html/_static/doctools.js +263 -0
- data/sphinx/_build/html/_static/down-pressed.png +0 -0
- data/sphinx/_build/html/_static/down.png +0 -0
- data/sphinx/_build/html/_static/file.png +0 -0
- data/sphinx/_build/html/_static/jquery-1.11.1.js +10308 -0
- data/sphinx/_build/html/_static/jquery.js +4 -0
- data/sphinx/_build/html/_static/minus.png +0 -0
- data/sphinx/_build/html/_static/plus.png +0 -0
- data/sphinx/_build/html/_static/pygments.css +63 -0
- data/sphinx/_build/html/_static/searchtools.js +651 -0
- data/sphinx/_build/html/_static/underscore-1.3.1.js +999 -0
- data/sphinx/_build/html/_static/underscore.js +31 -0
- data/sphinx/_build/html/_static/up-pressed.png +0 -0
- data/sphinx/_build/html/_static/up.png +0 -0
- data/sphinx/_build/html/_static/websupport.js +808 -0
- data/sphinx/_build/html/dvds.html +151 -0
- data/sphinx/_build/html/firewalls.html +397 -0
- data/sphinx/_build/html/genindex.html +114 -0
- data/sphinx/_build/html/images.html +236 -0
- data/sphinx/_build/html/index.html +571 -0
- data/sphinx/_build/html/load_balancers.html +409 -0
- data/sphinx/_build/html/logs.html +160 -0
- data/sphinx/_build/html/monitoring_center.html +160 -0
- data/sphinx/_build/html/monitoring_policies.html +530 -0
- data/sphinx/_build/html/objects.inv +0 -0
- data/sphinx/_build/html/private_networks.html +316 -0
- data/sphinx/_build/html/public_ips.html +215 -0
- data/sphinx/_build/html/rb-modindex.html +106 -0
- data/sphinx/_build/html/search.html +99 -0
- data/sphinx/_build/html/searchindex.js +1 -0
- data/sphinx/_build/html/server_appliances.html +153 -0
- data/sphinx/_build/html/servers.html +994 -0
- data/sphinx/_build/html/shared_storages.html +349 -0
- data/sphinx/_build/html/usages.html +140 -0
- data/sphinx/_build/html/users.html +363 -0
- data/sphinx/conf.py +287 -0
- data/sphinx/dvds.rst +42 -0
- data/sphinx/firewalls.rst +189 -0
- data/sphinx/images.rst +101 -0
- data/sphinx/index.rst +499 -0
- data/sphinx/load_balancers.rst +231 -0
- data/sphinx/logs.rst +55 -0
- data/sphinx/make.bat +263 -0
- data/sphinx/monitoring_center.rst +55 -0
- data/sphinx/monitoring_policies.rst +288 -0
- data/sphinx/private_networks.rst +146 -0
- data/sphinx/public_ips.rst +78 -0
- data/sphinx/server_appliances.rst +42 -0
- data/sphinx/servers.rst +630 -0
- data/sphinx/shared_storages.rst +160 -0
- data/sphinx/usages.rst +45 -0
- data/sphinx/users.rst +172 -0
- data/test/mock-api/add-firewall.json +66 -0
- data/test/mock-api/add-hdd.json +49 -0
- data/test/mock-api/add-lb.json +71 -0
- data/test/mock-api/add-new-ip.json +18 -0
- data/test/mock-api/add-pn.json +66 -0
- data/test/mock-api/add-port-mp.json +81 -0
- data/test/mock-api/add-process-mp.json +20 -0
- data/test/mock-api/add-rule-fp.json +33 -0
- data/test/mock-api/add-rule-lb.json +40 -0
- data/test/mock-api/add-server-ip.json +66 -0
- data/test/mock-api/add-server-mp.json +66 -0
- data/test/mock-api/assign-ip-fp.json +32 -0
- data/test/mock-api/assign-server-lb.json +39 -0
- data/test/mock-api/attach-server-pn.json +14 -0
- data/test/mock-api/attach-server-storage.json +24 -0
- data/test/mock-api/change-api-key.json +15 -0
- data/test/mock-api/change-password.json +5 -0
- data/test/mock-api/change-server-status.json +70 -0
- data/test/mock-api/clone-server.json +29 -0
- data/test/mock-api/create-fp.json +26 -0
- data/test/mock-api/create-image.json +30 -0
- data/test/mock-api/create-lb.json +33 -0
- data/test/mock-api/create-mp.json +81 -0
- data/test/mock-api/create-pn.json +11 -0
- data/test/mock-api/create-public-ip.json +10 -0
- data/test/mock-api/create-server.json +34 -0
- data/test/mock-api/create-snapshot.json +74 -0
- data/test/mock-api/create-storage.json +13 -0
- data/test/mock-api/create-user.json +14 -0
- data/test/mock-api/delete-fp.json +26 -0
- data/test/mock-api/delete-image.json +26 -0
- data/test/mock-api/delete-ip.json +15 -0
- data/test/mock-api/delete-lb.json +33 -0
- data/test/mock-api/delete-mp.json +71 -0
- data/test/mock-api/delete-pn.json +11 -0
- data/test/mock-api/delete-public-ip.json +10 -0
- data/test/mock-api/delete-rule-fp.json +26 -0
- data/test/mock-api/delete-server.json +50 -0
- data/test/mock-api/delete-snapshot.json +74 -0
- data/test/mock-api/delete-storage.json +24 -0
- data/test/mock-api/delete-user.json +15 -0
- data/test/mock-api/detach-server-lb.json +33 -0
- data/test/mock-api/detach-server-mp.json +65 -0
- data/test/mock-api/detach-server-storage.json +19 -0
- data/test/mock-api/edit-image.json +26 -0
- data/test/mock-api/eject-dvd.json +66 -0
- data/test/mock-api/fixed-server-flavors.json +70 -0
- data/test/mock-api/get-appliance.json +16 -0
- data/test/mock-api/get-dvd.json +9 -0
- data/test/mock-api/get-firewall.json +26 -0
- data/test/mock-api/get-fixed-server.json +17 -0
- data/test/mock-api/get-fp-rule.json +7 -0
- data/test/mock-api/get-hardware.json +13 -0
- data/test/mock-api/get-hdd.json +5 -0
- data/test/mock-api/get-image.json +26 -0
- data/test/mock-api/get-lb-rule.json +7 -0
- data/test/mock-api/get-lb-server.json +5 -0
- data/test/mock-api/get-load-balancer.json +33 -0
- data/test/mock-api/get-log.json +23 -0
- data/test/mock-api/get-monitoring-center.json +161 -0
- data/test/mock-api/get-mp-port.json +7 -0
- data/test/mock-api/get-mp-process.json +6 -0
- data/test/mock-api/get-mp-server.json +4 -0
- data/test/mock-api/get-mp.json +65 -0
- data/test/mock-api/get-pn-server.json +4 -0
- data/test/mock-api/get-private-network.json +20 -0
- data/test/mock-api/get-public-ip.json +10 -0
- data/test/mock-api/get-server-dvd.json +4 -0
- data/test/mock-api/get-server-image.json +4 -0
- data/test/mock-api/get-server-ip-fp.json +4 -0
- data/test/mock-api/get-server-ip.json +8 -0
- data/test/mock-api/get-server-pn.json +16 -0
- data/test/mock-api/get-server-status.json +4 -0
- data/test/mock-api/get-server-storage.json +5 -0
- data/test/mock-api/get-server.json +44 -0
- data/test/mock-api/get-storage.json +19 -0
- data/test/mock-api/get-usage.json +161 -0
- data/test/mock-api/get-user-api-key.json +3 -0
- data/test/mock-api/get-user-api.json +7 -0
- data/test/mock-api/get-user.json +15 -0
- data/test/mock-api/list-appliances.json +66 -0
- data/test/mock-api/list-credentials.json +5 -0
- data/test/mock-api/list-dvds.json +128 -0
- data/test/mock-api/list-firewalls.json +54 -0
- data/test/mock-api/list-fp-rules.json +16 -0
- data/test/mock-api/list-hdds.json +7 -0
- data/test/mock-api/list-images.json +54 -0
- data/test/mock-api/list-lb-rules.json +16 -0
- data/test/mock-api/list-lb-servers.json +12 -0
- data/test/mock-api/list-load-balancers.json +68 -0
- data/test/mock-api/list-logs.json +49 -0
- data/test/mock-api/list-monitoring-center-usages.json +90 -0
- data/test/mock-api/list-mp-ports.json +16 -0
- data/test/mock-api/list-mp-processes.json +14 -0
- data/test/mock-api/list-mp-servers.json +10 -0
- data/test/mock-api/list-mps.json +152 -0
- data/test/mock-api/list-pn-servers.json +10 -0
- data/test/mock-api/list-private-networks.json +24 -0
- data/test/mock-api/list-public-ips.json +44 -0
- data/test/mock-api/list-server-fps.json +4 -0
- data/test/mock-api/list-server-ips-fp.json +7 -0
- data/test/mock-api/list-server-ips.json +10 -0
- data/test/mock-api/list-server-lbs.json +6 -0
- data/test/mock-api/list-server-pns.json +6 -0
- data/test/mock-api/list-servers.json +66 -0
- data/test/mock-api/list-snapshots.json +7 -0
- data/test/mock-api/list-storages.json +47 -0
- data/test/mock-api/list-usages.json +144 -0
- data/test/mock-api/list-user-ips.json +5 -0
- data/test/mock-api/list-users.json +31 -0
- data/test/mock-api/load-dvd.json +63 -0
- data/test/mock-api/modify-fp.json +26 -0
- data/test/mock-api/modify-lb.json +33 -0
- data/test/mock-api/modify-mp.json +81 -0
- data/test/mock-api/modify-pn.json +20 -0
- data/test/mock-api/modify-port-mp.json +81 -0
- data/test/mock-api/modify-process-mp.json +73 -0
- data/test/mock-api/modify-public-ip.json +10 -0
- data/test/mock-api/modify-server-hardware.json +44 -0
- data/test/mock-api/modify-server-hdd.json +54 -0
- data/test/mock-api/modify-server.json +44 -0
- data/test/mock-api/modify-storage.json +19 -0
- data/test/mock-api/modify-user-api.json +15 -0
- data/test/mock-api/modify-user.json +15 -0
- data/test/mock-api/reinstall-image.json +52 -0
- data/test/mock-api/remove-firewall-policy.json +26 -0
- data/test/mock-api/remove-hdd.json +54 -0
- data/test/mock-api/remove-ip-fp.json +26 -0
- data/test/mock-api/remove-lb.json +66 -0
- data/test/mock-api/remove-pn.json +71 -0
- data/test/mock-api/remove-port-mp.json +73 -0
- data/test/mock-api/remove-process-mp.json +66 -0
- data/test/mock-api/remove-rule-lb.json +33 -0
- data/test/mock-api/remove-server-ip.json +58 -0
- data/test/mock-api/remove-server-pn.json +16 -0
- data/test/mock-api/restore-snapshot.json +55 -0
- data/test/mock-api/storage-servers.json +12 -0
- data/test/test_mock_dvd.rb +55 -0
- data/test/test_mock_firewall.rb +309 -0
- data/test/test_mock_image.rb +123 -0
- data/test/test_mock_load_balancer.rb +312 -0
- data/test/test_mock_log.rb +55 -0
- data/test/test_mock_monitoring_center.rb +55 -0
- data/test/test_mock_monitoring_policy.rb +587 -0
- data/test/test_mock_private_network.rb +206 -0
- data/test/test_mock_public_ip.rb +118 -0
- data/test/test_mock_server.rb +929 -0
- data/test/test_mock_server_appliance.rb +55 -0
- data/test/test_mock_shared_storage.rb +256 -0
- data/test/test_mock_usage.rb +34 -0
- data/test/test_mock_user.rb +270 -0
- metadata +360 -0
data/sphinx/dvds.rst
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
DVD's
|
2
|
+
*****************
|
3
|
+
|
4
|
+
.. rb:class:: OneAndOne::Dvd()
|
5
|
+
|
6
|
+
The :rb:class:`Dvd` class allows a user to perform actions against the 1and1 API.
|
7
|
+
|
8
|
+
|
9
|
+
.. rb:method:: list(page: nil, per_page: nil, sort: nil, q: nil, fields: nil)
|
10
|
+
|
11
|
+
List all DVD's on your account.
|
12
|
+
|
13
|
+
:param page: Allows the use of pagination. Indicate which page to start on.
|
14
|
+
:type page: ``int``
|
15
|
+
|
16
|
+
:param per_page: Number of items per page.
|
17
|
+
:type per_page: ``int``
|
18
|
+
|
19
|
+
:param sort: ``sort: 'name'`` retrieves a list of elements sorted
|
20
|
+
alphabetically. ``sort: 'creation_date'`` retrieves a list of elements
|
21
|
+
sorted by their creation date in descending order.
|
22
|
+
:type sort: ``str``
|
23
|
+
|
24
|
+
:param q: ``q`` is for query. Use this parameter to return only the items
|
25
|
+
that match your search query.
|
26
|
+
:type q: ``str``
|
27
|
+
|
28
|
+
:param fields: Returns only the parameters requested.
|
29
|
+
(i.e. fields: 'id, name, description, hardware.ram')
|
30
|
+
:type fields: ``str``
|
31
|
+
|
32
|
+
:rtype: JSON
|
33
|
+
|
34
|
+
|
35
|
+
.. rb:method:: get(dvd_id: nil)
|
36
|
+
|
37
|
+
Returns information about a DVD.
|
38
|
+
|
39
|
+
:param dvd_id: the unique identifier for the DVD.
|
40
|
+
:type dvd_id: ``str``
|
41
|
+
|
42
|
+
:rtype: JSON
|
@@ -0,0 +1,189 @@
|
|
1
|
+
Firewall Policies
|
2
|
+
*****************
|
3
|
+
|
4
|
+
.. rb:class:: OneAndOne::Firewall()
|
5
|
+
|
6
|
+
The :rb:class:`Firewall` class allows a user to perform actions against the 1and1 API.
|
7
|
+
|
8
|
+
|
9
|
+
.. rb:method:: list(page: nil, per_page: nil, sort: nil, q: nil, fields: nil)
|
10
|
+
|
11
|
+
Return a list of all shared storages.
|
12
|
+
|
13
|
+
:param page: Allows the use of pagination. Indicate which page to start on.
|
14
|
+
:type page: ``int``
|
15
|
+
|
16
|
+
:param per_page: Number of items per page.
|
17
|
+
:type per_page: ``int``
|
18
|
+
|
19
|
+
:param sort: ``sort: 'name'`` retrieves a list of elements sorted
|
20
|
+
alphabetically. ``sort: 'creation_date'`` retrieves a list of elements
|
21
|
+
sorted by their creation date in descending order.
|
22
|
+
:type sort: ``str``
|
23
|
+
|
24
|
+
:param q: ``q`` is for query. Use this parameter to return only the items
|
25
|
+
that match your search query.
|
26
|
+
:type q: ``str``
|
27
|
+
|
28
|
+
:param fields: Returns only the parameters requested.
|
29
|
+
(i.e. fields: 'id, name, description, hardware.ram')
|
30
|
+
:type fields: ``str``
|
31
|
+
|
32
|
+
:rtype: JSON
|
33
|
+
|
34
|
+
|
35
|
+
.. rb:method:: create(name: nil, description: nil, rules: nil)
|
36
|
+
|
37
|
+
Create a firewall policy.
|
38
|
+
|
39
|
+
:param name: firewall policy's name.
|
40
|
+
:type name: ``str``
|
41
|
+
|
42
|
+
:param description: firewall policy's name.
|
43
|
+
:type description: ``str``
|
44
|
+
|
45
|
+
:param rules: an array of rules for the new firewall policy.
|
46
|
+
:type rules: ``array``
|
47
|
+
|
48
|
+
:rtype: JSON
|
49
|
+
|
50
|
+
|
51
|
+
.. rb:method:: get(firewall_id: @id)
|
52
|
+
|
53
|
+
Returns a firewall policy's current specs.
|
54
|
+
|
55
|
+
:param firewall_id: the unique identifier for the firewall.
|
56
|
+
:type firewall_id: ``str``
|
57
|
+
|
58
|
+
:rtype: JSON
|
59
|
+
|
60
|
+
|
61
|
+
.. rb:method:: modify(firewall_id: @id, name: nil, description: nil)
|
62
|
+
|
63
|
+
Modify a firewall policy.
|
64
|
+
|
65
|
+
:param firewall_id: the unique identifier for the firewall policy.
|
66
|
+
:type firewall_id: ``str``
|
67
|
+
|
68
|
+
:param name: firewall policy name.
|
69
|
+
:type name: ``str``
|
70
|
+
|
71
|
+
:param description: firewall policy description.
|
72
|
+
:type description: ``str``
|
73
|
+
|
74
|
+
:rtype: JSON
|
75
|
+
|
76
|
+
|
77
|
+
.. rb:method:: delete(firewall_id: @id)
|
78
|
+
|
79
|
+
Delete a firewall policy.
|
80
|
+
|
81
|
+
:param firewall_id: the unique identifier for the firewall.
|
82
|
+
:type firewall_id: ``str``
|
83
|
+
|
84
|
+
:rtype: JSON
|
85
|
+
|
86
|
+
|
87
|
+
.. rb:method:: ips(firewall_id: @id)
|
88
|
+
|
89
|
+
Returns a list of the IPs assigned to a firewall policy.
|
90
|
+
|
91
|
+
:param firewall_id: the unique identifier for the firewall.
|
92
|
+
:type firewall_id: ``str``
|
93
|
+
|
94
|
+
:rtype: JSON
|
95
|
+
|
96
|
+
|
97
|
+
.. rb:method:: ip(firewall_id: @id, ip_id: nil)
|
98
|
+
|
99
|
+
Returns information about an IP assigned to a firewall policy.
|
100
|
+
|
101
|
+
:param firewall_id: the unique identifier for the firewall policy.
|
102
|
+
:type firewall_id: ``str``
|
103
|
+
|
104
|
+
:param ip_id: the unique identifier for the IP.
|
105
|
+
:type ip_id: ``str``
|
106
|
+
|
107
|
+
:rtype: JSON
|
108
|
+
|
109
|
+
|
110
|
+
.. rb:method:: add_ips(firewall_id: @id, ips: nil)
|
111
|
+
|
112
|
+
Add IPs to a firewall policy.
|
113
|
+
|
114
|
+
:param firewall_id: the unique identifier for the firewall policy.
|
115
|
+
:type firewall_id: ``str``
|
116
|
+
|
117
|
+
:param ips: an array of IP ID's for the new firewall policy..
|
118
|
+
:type ips: ``array``
|
119
|
+
|
120
|
+
:rtype: JSON
|
121
|
+
|
122
|
+
|
123
|
+
.. rb:method:: remove_ip(firewall_id: @id, ip_id: nil)
|
124
|
+
|
125
|
+
Remove an IP from a firewall policy.
|
126
|
+
|
127
|
+
:param firewall_id: the unique identifier for the firewall policy.
|
128
|
+
:type firewall_id: ``str``
|
129
|
+
|
130
|
+
:param ip_id: the unique identifier for the IP.
|
131
|
+
:type ip_id: ``str``
|
132
|
+
|
133
|
+
:rtype: JSON
|
134
|
+
|
135
|
+
|
136
|
+
.. rb:method:: rules(firewall_id: @id)
|
137
|
+
|
138
|
+
Returns a list the firewall policy's rules.
|
139
|
+
|
140
|
+
:param firewall_id: the unique identifier for the firewall.
|
141
|
+
:type firewall_id: ``str``
|
142
|
+
|
143
|
+
:rtype: JSON
|
144
|
+
|
145
|
+
|
146
|
+
.. rb:method:: rule(firewall_id: @id, rule_id: nil)
|
147
|
+
|
148
|
+
Returns information about a firewall policy's rule.
|
149
|
+
|
150
|
+
:param firewall_id: the unique identifier for the firewall policy.
|
151
|
+
:type firewall_id: ``str``
|
152
|
+
|
153
|
+
:param rule_id: the unique identifier for the firewall rule.
|
154
|
+
:type rule_id: ``str``
|
155
|
+
|
156
|
+
:rtype: JSON
|
157
|
+
|
158
|
+
|
159
|
+
.. rb:method:: add_rules(firewall_id: @id, rules: nil)
|
160
|
+
|
161
|
+
Add rules to a firewall policy.
|
162
|
+
|
163
|
+
:param firewall_id: the unique identifier for the firewall policy.
|
164
|
+
:type firewall_id: ``str``
|
165
|
+
|
166
|
+
:param rules: an array of rule objects.
|
167
|
+
:type rules: ``array``
|
168
|
+
|
169
|
+
:rtype: JSON
|
170
|
+
|
171
|
+
|
172
|
+
.. rb:method:: remove_rule(firewall_id: @id, rule_id: nil)
|
173
|
+
|
174
|
+
Remove a firewall policy's rule.
|
175
|
+
|
176
|
+
:param firewall_id: the unique identifier for the firewall policy.
|
177
|
+
:type firewall_id: ``str``
|
178
|
+
|
179
|
+
:param rule_id: the unique identifier for the firewall rule.
|
180
|
+
:type rule_id: ``str``
|
181
|
+
|
182
|
+
:rtype: JSON
|
183
|
+
|
184
|
+
|
185
|
+
.. rb:method:: wait_for()
|
186
|
+
|
187
|
+
Polls the firewall policy until an "ACTIVE" state is returned. Use this when chaining actions.
|
188
|
+
|
189
|
+
:rtype: ``nil``
|
data/sphinx/images.rst
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
Images
|
2
|
+
******
|
3
|
+
|
4
|
+
.. rb:class:: OneAndOne::Image()
|
5
|
+
|
6
|
+
The :rb:class:`Image` class allows a user to perform actions against the 1and1 API.
|
7
|
+
|
8
|
+
|
9
|
+
.. rb:method:: create(server_id: nil, name: nil, description: nil, frequency: nil, num_images: nil)
|
10
|
+
|
11
|
+
Create a new image.
|
12
|
+
|
13
|
+
:param server_id: the ID of the server to be copied.
|
14
|
+
:type server_id: ``str``
|
15
|
+
|
16
|
+
:param name: image name.
|
17
|
+
:type name: ``str``
|
18
|
+
|
19
|
+
:param description: image description.
|
20
|
+
:type description: ``str``
|
21
|
+
|
22
|
+
:param frequency: image creation policy. Possible values are ``'ONCE'``, ``'DAILY'``, and ``'WEEKLY'``.
|
23
|
+
:type frequency: ``str``
|
24
|
+
|
25
|
+
:param num_images: the number of images to create.
|
26
|
+
:type num_images: ``int``
|
27
|
+
|
28
|
+
:rtype: JSON
|
29
|
+
|
30
|
+
|
31
|
+
.. rb:method:: modify(image_id: @id, name: nil, description: nil, frequency: nil)
|
32
|
+
|
33
|
+
Modify an image.
|
34
|
+
|
35
|
+
:param image_id: the unique identifier for the image.
|
36
|
+
:type image_id: ``str``
|
37
|
+
|
38
|
+
:param name: image name.
|
39
|
+
:type name: ``str``
|
40
|
+
|
41
|
+
:param description: image description.
|
42
|
+
:type description: ``str``
|
43
|
+
|
44
|
+
:param frequency: can only be changed to ``'ONCE'``
|
45
|
+
:type frequency: ``str``
|
46
|
+
|
47
|
+
:rtype: JSON
|
48
|
+
|
49
|
+
|
50
|
+
.. rb:method:: delete(image_id: @id)
|
51
|
+
|
52
|
+
Delete an image.
|
53
|
+
|
54
|
+
:param image_id: the unique identifier for the image.
|
55
|
+
:type image_id: ``str``
|
56
|
+
|
57
|
+
:rtype: JSON
|
58
|
+
|
59
|
+
|
60
|
+
.. rb:method:: get(image_id: @id)
|
61
|
+
|
62
|
+
Retrieve an image's current specs.
|
63
|
+
|
64
|
+
:param image_id: the unique identifier for the image.
|
65
|
+
:type image_id: ``str``
|
66
|
+
|
67
|
+
:rtype: JSON
|
68
|
+
|
69
|
+
|
70
|
+
.. rb:method:: list(page: nil, per_page: nil, sort: nil, q: nil, fields: nil)
|
71
|
+
|
72
|
+
Return a list of all images.
|
73
|
+
|
74
|
+
:param page: Allows the use of pagination. Indicate which page to start on.
|
75
|
+
:type page: ``int``
|
76
|
+
|
77
|
+
:param per_page: Number of items per page.
|
78
|
+
:type per_page: ``int``
|
79
|
+
|
80
|
+
:param sort: ``sort: 'name'`` retrieves a list of elements sorted
|
81
|
+
alphabetically. ``sort: 'creation_date'`` retrieves a list of elements
|
82
|
+
sorted by their creation date in descending order.
|
83
|
+
:type sort: ``str``
|
84
|
+
|
85
|
+
:param q: ``q`` is for query. Use this parameter to return only the items
|
86
|
+
that match your search query.
|
87
|
+
:type q: ``str``
|
88
|
+
|
89
|
+
:param fields: Returns only the parameters requested.
|
90
|
+
(i.e. fields: 'id, name, description, hardware.ram')
|
91
|
+
:type fields: ``str``
|
92
|
+
|
93
|
+
:rtype: JSON
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
.. rb:method:: wait_for()
|
98
|
+
|
99
|
+
Polls the image until an "ACTIVE" state is returned. Use this when chaining actions.
|
100
|
+
|
101
|
+
:rtype: ``nil``
|
data/sphinx/index.rst
ADDED
@@ -0,0 +1,499 @@
|
|
1
|
+
1&1's Ruby SDK
|
2
|
+
****************
|
3
|
+
|
4
|
+
The 1&1 Ruby SDK is a Ruby gem used for interacting with the 1&1
|
5
|
+
platform over the REST API.
|
6
|
+
|
7
|
+
This guide will show you how to programmatically use the 1&1 library to perform
|
8
|
+
common management tasks also available through the 1&1 Control Panel.
|
9
|
+
|
10
|
+
|
11
|
+
Concepts
|
12
|
+
========
|
13
|
+
|
14
|
+
The Ruby Client Library wraps the latest version of the 1&1 REST API. All
|
15
|
+
API operations are performed over SSL and authenticated using your 1&1 API Token.
|
16
|
+
The API can be accessed within an instance running in 1&1 or directly over
|
17
|
+
the Internet from any application that can send an HTTPS request and receive
|
18
|
+
an HTTPS response.
|
19
|
+
|
20
|
+
|
21
|
+
Getting Started
|
22
|
+
===============
|
23
|
+
|
24
|
+
Before you begin you will need to have signed-up for a 1&1 account. The
|
25
|
+
credentials you setup during sign-up will be used to authenticate against the API.
|
26
|
+
|
27
|
+
|
28
|
+
Installation
|
29
|
+
============
|
30
|
+
|
31
|
+
You can install the latest stable version using::
|
32
|
+
|
33
|
+
$ gem install 1and1
|
34
|
+
|
35
|
+
Done!
|
36
|
+
|
37
|
+
|
38
|
+
Authentication
|
39
|
+
==============
|
40
|
+
|
41
|
+
Start your application by calling the :rb:func:`OneAndOne.start` method
|
42
|
+
with your API Token::
|
43
|
+
|
44
|
+
require 'oneandone'
|
45
|
+
|
46
|
+
OneAndOne.start('<API-TOKEN>')
|
47
|
+
|
48
|
+
|
49
|
+
If you have yet to create your API Token, follow the
|
50
|
+
instructions below:
|
51
|
+
|
52
|
+
1. From the 1&1 Control Panel, click Management > Users.
|
53
|
+
2. In the Users section, click Create.
|
54
|
+
3. Enter the desired user name.
|
55
|
+
4. In the Password field, enter the password and repeat it.
|
56
|
+
5. Enter the desired e-mail address.
|
57
|
+
6. Click Create.
|
58
|
+
7. Select the created user
|
59
|
+
8. In the details of the User, in the API section, click on "Disabled".
|
60
|
+
9. Click Yes.
|
61
|
+
10. Click Apply Changes.
|
62
|
+
11. In the API Key section, click Display User Information. The API Key will be displayed.
|
63
|
+
|
64
|
+
|
65
|
+
.. note:: You can now perform requests using any of the module's class methods outlined in the Table of Contents below.
|
66
|
+
|
67
|
+
|
68
|
+
Table of Contents
|
69
|
+
=================
|
70
|
+
|
71
|
+
.. toctree::
|
72
|
+
:maxdepth: 2
|
73
|
+
|
74
|
+
servers
|
75
|
+
images
|
76
|
+
shared_storages
|
77
|
+
firewalls
|
78
|
+
load_balancers
|
79
|
+
public_ips
|
80
|
+
private_networks
|
81
|
+
monitoring_center
|
82
|
+
monitoring_policies
|
83
|
+
logs
|
84
|
+
users
|
85
|
+
usages
|
86
|
+
server_appliances
|
87
|
+
dvds
|
88
|
+
|
89
|
+
|
90
|
+
Resources
|
91
|
+
=========
|
92
|
+
|
93
|
+
.. _API: https://cloudpanel-api.1and1.com/documentation/v1/#
|
94
|
+
.. _Github: https://github.com/1and1/oneandone-cloudserver-sdk-ruby
|
95
|
+
|
96
|
+
Official 1&1 REST API Documentation: API_
|
97
|
+
|
98
|
+
1&1 Ruby SDK Repo: Github_
|
99
|
+
|
100
|
+
|
101
|
+
Create Server
|
102
|
+
=======================
|
103
|
+
|
104
|
+
::
|
105
|
+
|
106
|
+
require 'oneandone'
|
107
|
+
|
108
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API Key
|
109
|
+
|
110
|
+
|
111
|
+
# Instantiate Server Object
|
112
|
+
server = OneAndOne::Server.new()
|
113
|
+
|
114
|
+
# Create HDD's
|
115
|
+
hdd1 = {
|
116
|
+
'size' => 120,
|
117
|
+
'is_main' => true
|
118
|
+
}
|
119
|
+
|
120
|
+
hdds = [hdd1]
|
121
|
+
|
122
|
+
# Perform Request
|
123
|
+
response = server.create(name: 'Example Server',
|
124
|
+
vcore: 1,
|
125
|
+
cores_per_processor: 1,
|
126
|
+
ram: 1,
|
127
|
+
appliance_id: '<IMAGE-ID>',
|
128
|
+
hdds: hdds)
|
129
|
+
|
130
|
+
puts JSON.pretty_generate(response)
|
131
|
+
|
132
|
+
|
133
|
+
Create Firewall Policy
|
134
|
+
=======================
|
135
|
+
|
136
|
+
::
|
137
|
+
|
138
|
+
require 'oneandone'
|
139
|
+
|
140
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API Key
|
141
|
+
|
142
|
+
|
143
|
+
# Instantiate Firewall Object
|
144
|
+
firewall = OneAndOne::Firewall.new()
|
145
|
+
|
146
|
+
# Create Rules
|
147
|
+
rule1 = {
|
148
|
+
'protocol' => 'TCP',
|
149
|
+
'port_from' => 80,
|
150
|
+
'port_to' => 80,
|
151
|
+
'source' => '0.0.0.0'
|
152
|
+
}
|
153
|
+
|
154
|
+
rules = [rule1]
|
155
|
+
|
156
|
+
# Perform Request
|
157
|
+
response = firewall.create(name: 'Test Firewall',
|
158
|
+
description: 'Example Desc',
|
159
|
+
rules: rules)
|
160
|
+
|
161
|
+
puts JSON.pretty_generate(response)
|
162
|
+
|
163
|
+
|
164
|
+
Create Load Balancer
|
165
|
+
=======================
|
166
|
+
|
167
|
+
::
|
168
|
+
|
169
|
+
require 'oneandone'
|
170
|
+
|
171
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API Key
|
172
|
+
|
173
|
+
|
174
|
+
# Instantiate Load Balancer Object
|
175
|
+
load_balancer = OneAndOne::LoadBalancer.new()
|
176
|
+
|
177
|
+
# Create Rules
|
178
|
+
rule1 = {
|
179
|
+
'protocol' => 'TCP',
|
180
|
+
'port_balancer' => 80,
|
181
|
+
'port_server' => 80,
|
182
|
+
'source' => '0.0.0.0'
|
183
|
+
}
|
184
|
+
|
185
|
+
rules = [rule1]
|
186
|
+
|
187
|
+
# Perform Request
|
188
|
+
response = load_balancer.create(name: 'Test LB',
|
189
|
+
description: 'Example Desc',
|
190
|
+
health_check_test: 'TCP',
|
191
|
+
health_check_interval: 40,
|
192
|
+
persistence: true,
|
193
|
+
persistence_time: 1200,
|
194
|
+
method: 'ROUND_ROBIN',
|
195
|
+
rules: rules)
|
196
|
+
|
197
|
+
puts JSON.pretty_generate(response)
|
198
|
+
|
199
|
+
|
200
|
+
Create Monitoring Policy
|
201
|
+
=========================
|
202
|
+
|
203
|
+
::
|
204
|
+
|
205
|
+
require 'oneandone'
|
206
|
+
|
207
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API Key
|
208
|
+
|
209
|
+
|
210
|
+
# Instantiate Monitoring Policy Object
|
211
|
+
monitoring_policy = OneAndOne::MonitoringPolicy.new()
|
212
|
+
|
213
|
+
# Create Threshold Limits
|
214
|
+
thresholds = {
|
215
|
+
'cpu' => {
|
216
|
+
'warning' => {
|
217
|
+
'value' => 90,
|
218
|
+
'alert' => false
|
219
|
+
},
|
220
|
+
'critical' => {
|
221
|
+
'value' => 95,
|
222
|
+
'alert' => false
|
223
|
+
}
|
224
|
+
},
|
225
|
+
'ram' => {
|
226
|
+
'warning' => {
|
227
|
+
'value' => 90,
|
228
|
+
'alert' => false
|
229
|
+
},
|
230
|
+
'critical' => {
|
231
|
+
'value' => 95,
|
232
|
+
'alert' => false
|
233
|
+
}
|
234
|
+
},
|
235
|
+
'disk' => {
|
236
|
+
'warning' => {
|
237
|
+
'value' => 90,
|
238
|
+
'alert' => false
|
239
|
+
},
|
240
|
+
'critical' => {
|
241
|
+
'value' => 95,
|
242
|
+
'alert' => false
|
243
|
+
}
|
244
|
+
},
|
245
|
+
'transfer' => {
|
246
|
+
'warning' => {
|
247
|
+
'value' => 1000,
|
248
|
+
'alert' => false
|
249
|
+
},
|
250
|
+
'critical' => {
|
251
|
+
'value' => 2000,
|
252
|
+
'alert' => false
|
253
|
+
}
|
254
|
+
},
|
255
|
+
'internal_ping' => {
|
256
|
+
'warning' => {
|
257
|
+
'value' => 50,
|
258
|
+
'alert' => false
|
259
|
+
},
|
260
|
+
'critical' => {
|
261
|
+
'value' => 100,
|
262
|
+
'alert' => false
|
263
|
+
}
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
# Create Ports
|
268
|
+
port1 = {
|
269
|
+
'protocol' => 'TCP',
|
270
|
+
'port' => 80,
|
271
|
+
'alert_if' => 'NOT_RESPONDING',
|
272
|
+
'email_notification' => true
|
273
|
+
}
|
274
|
+
|
275
|
+
ports = [port1]
|
276
|
+
|
277
|
+
# Create Processes
|
278
|
+
process1 = {
|
279
|
+
'process' => 'test',
|
280
|
+
'alert_if' => 'NOT_RUNNING',
|
281
|
+
'email_notification' => true
|
282
|
+
}
|
283
|
+
|
284
|
+
processes = [process1]
|
285
|
+
|
286
|
+
# Perform Request
|
287
|
+
response = monitoring_policy.create(name: 'Test Monitoring Policy',
|
288
|
+
email: 'test@example.com',
|
289
|
+
agent: true,
|
290
|
+
thresholds: thresholds,
|
291
|
+
ports: ports,
|
292
|
+
processes: processes)
|
293
|
+
|
294
|
+
puts JSON.pretty_generate(response)
|
295
|
+
|
296
|
+
Then, add a server or two:
|
297
|
+
|
298
|
+
::
|
299
|
+
|
300
|
+
# Add Servers
|
301
|
+
server1 = '<SERVER-ID>'
|
302
|
+
server2 = '<SERVER-ID>'
|
303
|
+
|
304
|
+
servers = [server1, server2]
|
305
|
+
|
306
|
+
# Perform Request
|
307
|
+
response = monitoring_policy.add_servers(servers: servers)
|
308
|
+
|
309
|
+
puts JSON.pretty_generate(response)
|
310
|
+
|
311
|
+
|
312
|
+
Update Server Cores, Memory, and Disk
|
313
|
+
=====================================
|
314
|
+
|
315
|
+
1&1 allows users to dynamically update cores, memory, and disk independently of each other. This removes the restriction of needing to upgrade to the next size up to receive an increase in memory. You can now simply increase the instances memory keeping your costs in-line with your resource needs.
|
316
|
+
|
317
|
+
The following code illustrates how you can update cores and memory:
|
318
|
+
|
319
|
+
::
|
320
|
+
|
321
|
+
require 'oneandone'
|
322
|
+
|
323
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API Key
|
324
|
+
|
325
|
+
|
326
|
+
# Instantiate Server Object
|
327
|
+
server = OneAndOne::Server.new()
|
328
|
+
|
329
|
+
# Perform Request
|
330
|
+
response = server.modify_hardware(server_id: '<SERVER-ID>',
|
331
|
+
vcore: 2,
|
332
|
+
ram: 6)
|
333
|
+
|
334
|
+
puts JSON.pretty_generate(response)
|
335
|
+
|
336
|
+
This is how you would update a server disk's size:
|
337
|
+
|
338
|
+
::
|
339
|
+
|
340
|
+
require 'oneandone'
|
341
|
+
|
342
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API Key
|
343
|
+
|
344
|
+
|
345
|
+
# Instantiate Server Object
|
346
|
+
server = OneAndOne::Server.new()
|
347
|
+
|
348
|
+
# Perform Request
|
349
|
+
response = server.modify_hdd(server_id: '<SERVER-ID>',
|
350
|
+
hdd_id: '<HDD-ID>',
|
351
|
+
size: 140)
|
352
|
+
|
353
|
+
puts JSON.pretty_generate(response)
|
354
|
+
|
355
|
+
|
356
|
+
Example App
|
357
|
+
============
|
358
|
+
|
359
|
+
This simple app creates a load balancer, firewall policy, and server. It then creates a new IP for the server and adds the load balancer and firewall policy to that IP.
|
360
|
+
|
361
|
+
Use the ``wait_for`` method to chain together multiple actions that take some time to deploy.
|
362
|
+
|
363
|
+
::
|
364
|
+
|
365
|
+
require_relative '../lib/oneandone'
|
366
|
+
|
367
|
+
OneAndOne.start('<API-TOKEN>') # Init module with API key
|
368
|
+
|
369
|
+
|
370
|
+
|
371
|
+
### Create load balancer
|
372
|
+
load_balancer = OneAndOne::LoadBalancer.new
|
373
|
+
|
374
|
+
rule1 = {
|
375
|
+
'protocol' => 'TCP',
|
376
|
+
'port_balancer' => 80,
|
377
|
+
'port_server' => 80,
|
378
|
+
'source' => '0.0.0.0'
|
379
|
+
}
|
380
|
+
|
381
|
+
rules = [rule1]
|
382
|
+
|
383
|
+
lb1 = load_balancer.create(name: 'Example App LB',
|
384
|
+
description: 'Example Desc',
|
385
|
+
health_check_test: 'TCP',
|
386
|
+
health_check_interval: 40,
|
387
|
+
persistence: true,
|
388
|
+
persistence_time: 1200,
|
389
|
+
method: 'ROUND_ROBIN',
|
390
|
+
rules: rules)
|
391
|
+
|
392
|
+
# Wait for load balancer to deploy
|
393
|
+
puts "Creating load balancer..."
|
394
|
+
load_balancer.wait_for
|
395
|
+
|
396
|
+
|
397
|
+
|
398
|
+
### Create firewall policy
|
399
|
+
firewall = OneAndOne::Firewall.new()
|
400
|
+
|
401
|
+
rule1 = {
|
402
|
+
'protocol' => 'TCP',
|
403
|
+
'port_from' => 80,
|
404
|
+
'port_to' => 80,
|
405
|
+
'source' => '0.0.0.0'
|
406
|
+
}
|
407
|
+
|
408
|
+
rules = [rule1]
|
409
|
+
|
410
|
+
fp1 = firewall.create(name: 'Example App Firewall',
|
411
|
+
description: 'Example Desc',
|
412
|
+
rules: rules)
|
413
|
+
|
414
|
+
# Wait for firewall policy to deploy
|
415
|
+
puts "Creating firewall policy..."
|
416
|
+
firewall.wait_for
|
417
|
+
|
418
|
+
|
419
|
+
|
420
|
+
### Create a server
|
421
|
+
server = OneAndOne::Server.new()
|
422
|
+
|
423
|
+
hdd1 = {
|
424
|
+
'size' => 120,
|
425
|
+
'is_main' => true
|
426
|
+
}
|
427
|
+
|
428
|
+
hdds = [hdd1]
|
429
|
+
|
430
|
+
server1 = server.create(name: 'Example App Server',
|
431
|
+
vcore: 1,
|
432
|
+
cores_per_processor: 1,
|
433
|
+
ram: 1,
|
434
|
+
appliance_id: '<IMAGE-ID>',
|
435
|
+
hdds: hdds)
|
436
|
+
|
437
|
+
# Wait for server to deploy
|
438
|
+
puts "Creating server..."
|
439
|
+
server.wait_for
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
### Add a new IP to the server
|
444
|
+
puts "Adding an IP to the server..."
|
445
|
+
response = server.add_ip
|
446
|
+
new_ip = response['ips'][1]['id']
|
447
|
+
|
448
|
+
|
449
|
+
|
450
|
+
### Add the load balancer to the new IP
|
451
|
+
response = server.add_load_balancer(ip_id: new_ip,
|
452
|
+
load_balancer_id: load_balancer.id)
|
453
|
+
|
454
|
+
# Wait for load balancer to be added
|
455
|
+
puts "Adding load balancer to new server IP..."
|
456
|
+
server.wait_for
|
457
|
+
|
458
|
+
|
459
|
+
|
460
|
+
### Add the firewall policy to the new IP
|
461
|
+
response = server.add_firewall(ip_id: new_ip,
|
462
|
+
firewall_id: firewall.id)
|
463
|
+
|
464
|
+
# Wait for firewall policy to be added
|
465
|
+
puts "Adding firewall policy to new server IP..."
|
466
|
+
server.wait_for
|
467
|
+
puts "Everything looks good!"
|
468
|
+
|
469
|
+
|
470
|
+
|
471
|
+
### Cleanup
|
472
|
+
puts "Let's clean up the mess we just made."
|
473
|
+
|
474
|
+
puts "Deleting server..."
|
475
|
+
response = server.delete
|
476
|
+
puts "Success!"
|
477
|
+
|
478
|
+
puts "Deleting load balancer..."
|
479
|
+
response = load_balancer.delete
|
480
|
+
puts "Success!"
|
481
|
+
|
482
|
+
puts "Deleting firewall policy..."
|
483
|
+
response = firewall.delete
|
484
|
+
puts "Success!"
|
485
|
+
|
486
|
+
puts "All done!"
|
487
|
+
|
488
|
+
|
489
|
+
|
490
|
+
|
491
|
+
Index
|
492
|
+
==================
|
493
|
+
|
494
|
+
* :ref:`search`
|
495
|
+
|
496
|
+
|
497
|
+
|
498
|
+
.. Create top-level module
|
499
|
+
.. rb:module:: OneAndOne
|