fog-openstack 0.1.1 → 0.1.2

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 +4 -4
  2. data/.gitignore +1 -1
  3. data/.hound.yml +2 -0
  4. data/.rubocop.yml +93 -0
  5. data/.travis.yml +13 -10
  6. data/{lib/fog/openstack/CHANGELOG.md → CHANGELOG.md} +0 -0
  7. data/CODE_OF_CONDUCT.md +1 -1
  8. data/Gemfile +2 -0
  9. data/README.md +497 -3
  10. data/Rakefile +5 -1
  11. data/fog-openstack.gemspec +8 -7
  12. data/gemfiles/Gemfile-1.9 +16 -0
  13. data/lib/fog/openstack.rb +55 -30
  14. data/lib/fog/openstack/docs/metering.md +29 -0
  15. data/lib/fog/openstack/metering.rb +6 -1
  16. data/lib/fog/openstack/models/metering/event.rb +16 -0
  17. data/lib/fog/openstack/models/metering/events.rb +23 -0
  18. data/lib/fog/openstack/models/network/floating_ip.rb +1 -24
  19. data/lib/fog/openstack/models/network/ike_policies.rb +32 -0
  20. data/lib/fog/openstack/models/network/ike_policy.rb +43 -0
  21. data/lib/fog/openstack/models/network/ipsec_policies.rb +32 -0
  22. data/lib/fog/openstack/models/network/ipsec_policy.rb +45 -0
  23. data/lib/fog/openstack/models/network/ipsec_site_connection.rb +51 -0
  24. data/lib/fog/openstack/models/network/ipsec_site_connections.rb +33 -0
  25. data/lib/fog/openstack/models/network/vpn_service.rb +42 -0
  26. data/lib/fog/openstack/models/network/vpn_services.rb +32 -0
  27. data/lib/fog/openstack/network.rb +52 -13
  28. data/lib/fog/openstack/requests/compute/create_volume.rb +28 -21
  29. data/lib/fog/openstack/requests/metering/get_event.rb +27 -0
  30. data/lib/fog/openstack/requests/metering/list_events.rb +42 -0
  31. data/lib/fog/openstack/requests/network/associate_floating_ip.rb +15 -10
  32. data/lib/fog/openstack/requests/network/create_floating_ip.rb +1 -1
  33. data/lib/fog/openstack/requests/network/create_ike_policy.rb +53 -0
  34. data/lib/fog/openstack/requests/network/create_ipsec_policy.rb +53 -0
  35. data/lib/fog/openstack/requests/network/create_ipsec_site_connection.rb +66 -0
  36. data/lib/fog/openstack/requests/network/create_vpn_service.rb +51 -0
  37. data/lib/fog/openstack/requests/network/delete_ike_policy.rb +28 -0
  38. data/lib/fog/openstack/requests/network/delete_ipsec_policy.rb +28 -0
  39. data/lib/fog/openstack/requests/network/delete_ipsec_site_connection.rb +29 -0
  40. data/lib/fog/openstack/requests/network/delete_vpn_service.rb +28 -0
  41. data/lib/fog/openstack/requests/network/disassociate_floating_ip.rb +15 -10
  42. data/lib/fog/openstack/requests/network/get_floating_ip.rb +12 -2
  43. data/lib/fog/openstack/requests/network/get_ike_policy.rb +28 -0
  44. data/lib/fog/openstack/requests/network/get_ipsec_policy.rb +28 -0
  45. data/lib/fog/openstack/requests/network/get_ipsec_site_connection.rb +28 -0
  46. data/lib/fog/openstack/requests/network/get_network.rb +1 -13
  47. data/lib/fog/openstack/requests/network/get_vpn_service.rb +28 -0
  48. data/lib/fog/openstack/requests/network/list_ike_policies.rb +25 -0
  49. data/lib/fog/openstack/requests/network/list_ipsec_policies.rb +25 -0
  50. data/lib/fog/openstack/requests/network/list_ipsec_site_connections.rb +25 -0
  51. data/lib/fog/openstack/requests/network/list_vpn_services.rb +25 -0
  52. data/lib/fog/openstack/requests/network/update_ike_policy.rb +49 -0
  53. data/lib/fog/openstack/requests/network/update_ipsec_policy.rb +52 -0
  54. data/lib/fog/openstack/requests/network/update_ipsec_site_connection.rb +64 -0
  55. data/lib/fog/openstack/requests/network/update_vpn_service.rb +46 -0
  56. data/lib/fog/openstack/storage.rb +2 -2
  57. data/lib/fog/openstack/version.rb +1 -1
  58. data/tests/helper.rb +3 -0
  59. data/tests/openstack/models/network/ike_policies_tests.rb +28 -0
  60. data/tests/openstack/models/network/ike_policy_tests.rb +36 -0
  61. data/tests/openstack/models/network/ipsec_policies_tests.rb +26 -0
  62. data/tests/openstack/models/network/ipsec_policy_tests.rb +36 -0
  63. data/tests/openstack/models/network/ipsec_site_connection_tests.rb +50 -0
  64. data/tests/openstack/models/network/ipsec_site_connections_tests.rb +32 -0
  65. data/tests/openstack/models/network/vpn_service_tests.rb +27 -0
  66. data/tests/openstack/models/network/vpn_services_tests.rb +22 -0
  67. data/tests/openstack/requests/metering/event_tests.rb +17 -0
  68. data/tests/openstack/requests/network/ike_policy_tests.rb +65 -0
  69. data/tests/openstack/requests/network/ipsec_policy_tests.rb +65 -0
  70. data/tests/openstack/requests/network/ipsec_site_connection_tests.rb +82 -0
  71. data/tests/openstack/requests/network/vpn_service_tests.rb +61 -0
  72. metadata +109 -47
  73. data/CONTRIBUTORS.md +0 -79
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4191e18e2e5e919b0eb167af4639b9d39454e1b8
4
- data.tar.gz: 9514f40c05dacd2d2df860a23d83c2a84be900c1
3
+ metadata.gz: e3c4d1c427e750aa77389354355ca0f437fc70e0
4
+ data.tar.gz: bbeae160627a5fcf20fdf5278bbcf766a3a60e49
5
5
  SHA512:
6
- metadata.gz: 8ba895b6f1e19022fe1b904470302e3a3a2a3e0e7b693fae7b17fe613924a6d330928c2a1fc37822504b4e92265406c9f928da4b7c9b7e17291714601287b94c
7
- data.tar.gz: d1768d3a0d270ad6b7e7127ce32b6b3d1aadeb7db5171596016e3f7e892492c1638dc238f8ff5f9d8d559e61c6887e0e94c14c82c8b82823fb346cf9ce425003
6
+ metadata.gz: 5e2d9bb935bcbee9cde4705d8c40ceb0c74ccda1f4965cbb270be9c31d7bda7e453878fd3340082aff9725ba1745029b90b8140b70878919c1297fa3ef4be51c
7
+ data.tar.gz: deb48e9bac485300c4349e463a3865facc4fc157f8096f5a856e57c3b4a3bedb5e1ff5f66f3e14c38821459e583a1a94f9e33686b14ced362851ad7aff08a4a6
data/.gitignore CHANGED
@@ -7,4 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
- *.gem
10
+ gemfiles/Gemfile-1.9.lock
data/.hound.yml ADDED
@@ -0,0 +1,2 @@
1
+ ruby:
2
+ config_file: .rubocop.yml
data/.rubocop.yml ADDED
@@ -0,0 +1,93 @@
1
+ #
2
+ # Overrides
3
+ #
4
+ AbcSize:
5
+ Severity: refactor
6
+ AlignHash:
7
+ EnforcedHashRocketStyle: table
8
+ EnforcedColonStyle: table
9
+ BlockNesting:
10
+ Severity: refactor
11
+ ClassLength:
12
+ Severity: refactor
13
+ ClassCheck:
14
+ EnforcedStyle: kind_of?
15
+ CollectionMethods:
16
+ PreferredMethods:
17
+ find: detect
18
+ find_all: select
19
+ map: collect
20
+ reduce: inject
21
+ CyclomaticComplexity:
22
+ Severity: refactor
23
+ FormatString:
24
+ EnforcedStyle: percent
25
+ HashSyntax:
26
+ EnforcedStyle: hash_rockets
27
+ LineLength:
28
+ Max: 120
29
+ Severity: refactor
30
+ MethodLength:
31
+ Max: 25
32
+ Severity: refactor
33
+ ParameterLists:
34
+ Severity: refactor
35
+ PerceivedComplexity:
36
+ Severity: refactor
37
+ RedundantReturn:
38
+ AllowMultipleReturnValues: true
39
+ SignalException:
40
+ EnforcedStyle: only_raise
41
+ SingleLineMethods:
42
+ AllowIfMethodIsEmpty: false
43
+ SpaceInsideHashLiteralBraces:
44
+ EnforcedStyle: no_space
45
+ TrivialAccessors:
46
+ AllowPredicates: true
47
+ #
48
+ # Enabled/Disabled
49
+ #
50
+ ClassAndModuleChildren:
51
+ Enabled: false
52
+ DefEndAlignment:
53
+ AutoCorrect: true
54
+ Documentation:
55
+ Enabled: false
56
+ Encoding:
57
+ Enabled: false
58
+ EndAlignment:
59
+ AutoCorrect: true
60
+ ExtraSpacing:
61
+ AutoCorrect: false # https://github.com/bbatsov/rubocop/issues/2280
62
+ FindEach:
63
+ Enabled: false
64
+ GuardClause:
65
+ Enabled: false
66
+ IfUnlessModifier:
67
+ Enabled: false
68
+ NumericLiterals:
69
+ AutoCorrect: false
70
+ ParallelAssignment:
71
+ Enabled: false
72
+ PerlBackrefs:
73
+ Enabled: false
74
+ ReadWriteAttribute:
75
+ AutoCorrect: false
76
+ RescueModifier:
77
+ AutoCorrect: false
78
+ SingleLineBlockParams:
79
+ Enabled: false
80
+ SpaceBeforeFirstArg:
81
+ Enabled: false
82
+ SpecialGlobalVars:
83
+ AutoCorrect: false
84
+ StringLiterals:
85
+ Enabled: false
86
+ StringLiteralsInInterpolation:
87
+ Enabled: false
88
+ TrailingCommaInLiteral:
89
+ Enabled: false
90
+ WhileUntilModifier:
91
+ Enabled: false
92
+ WordArray:
93
+ AutoCorrect: false
data/.travis.yml CHANGED
@@ -1,30 +1,33 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  script: bundle exec rake test
4
+ env: JRUBY_OPTS=--debug
4
5
  matrix:
5
6
  fast_finish: true
6
7
  include:
7
- - rvm: 1.8.7
8
- gemfile: gemfiles/Gemfile-ruby-1.8.7
9
8
  - rvm: 1.9.3
10
- gemfile: Gemfile
9
+ gemfile: gemfiles/Gemfile-1.9
11
10
  - rvm: 2.0.0
12
11
  gemfile: Gemfile
13
12
  - rvm: 2.1.0
14
13
  gemfile: Gemfile
15
14
  - rvm: 2.1.1
16
15
  gemfile: Gemfile
17
- - rvm: 2.1.1
18
- gemfile: gemfiles/Gemfile-edge
19
16
  - rvm: 2.2.0
20
17
  gemfile: Gemfile
21
- - rvm: 2.2.0
22
- gemfile: gemfiles/Gemfile-edge
23
- - rvm: jruby-18mode
24
- gemfile: gemfiles/Gemfile-ruby-1.8.7
25
- - rvm: jruby-19mode
18
+ - rvm: 2.3.0
26
19
  gemfile: Gemfile
20
+ - rvm: jruby-19mode
21
+ gemfile: gemfiles/Gemfile-1.9
27
22
  - rvm: jruby-head
28
23
  gemfile: Gemfile
29
24
  allow_failures:
30
25
  - rvm: jruby-head
26
+ notifications:
27
+ webhooks:
28
+ urls:
29
+ - https://webhooks.gitter.im/e/af95aadff4470a9732b9
30
+ on_success: change
31
+ on_failure: always
32
+ on_start: never
33
+ email: false
File without changes
data/CODE_OF_CONDUCT.md CHANGED
@@ -46,4 +46,4 @@ version 1.3.0, available at
46
46
  [http://contributor-covenant.org/version/1/3/0/][version]
47
47
 
48
48
  [homepage]: http://contributor-covenant.org
49
- [version]: http://contributor-covenant.org/version/1/3/0/
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem "coveralls", require: false
4
+
3
5
  # Specify your gem's dependencies in fog-openstack.gemspec
4
6
  gemspec
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Fog::Openstack
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/fog/openstack`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Gem Version](https://badge.fury.io/rb/fog-openstack.svg)](http://badge.fury.io/rb/fog-openstack) [![Build Status](https://travis-ci.org/fog/fog-openstack.svg?branch=master)](https://travis-ci.org/fog/fog-openstack) [![Dependency Status](https://gemnasium.com/fog/fog-openstack.svg)](https://gemnasium.com/fog/fog-openstack) [![Coverage Status](https://coveralls.io/repos/github/fog/fog-openstack/badge.svg?branch=master)](https://coveralls.io/github/fog/fog-openstack?branch=master) [![Code Climate](https://codeclimate.com/github/fog/fog-openstack.png)](https://codeclimate.com/github/fog/fog-openstack) [![Join the chat at https://gitter.im/fog/fog-openstack](https://badges.gitter.im/fog/fog-openstack.svg)](https://gitter.im/fog/fog-openstack?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ This is the plugin Gem to talk to [OpenStack](http://openstack.org) clouds via fog.
6
+
7
+ The main maintainers for the OpenStack sections are @dhague, @Ladas, @seanhandley, @mdarby and @jjasghar. Please send CC them on pull requests.
6
8
 
7
9
  ## Installation
8
10
 
@@ -22,7 +24,499 @@ Or install it yourself as:
22
24
 
23
25
  ## Usage
24
26
 
25
- TODO: Write usage instructions here
27
+ ### Initial Setup
28
+
29
+ Require the gem:
30
+
31
+ ```ruby
32
+ require "fog/openstack"
33
+ ```
34
+
35
+ Checklist:
36
+
37
+ * Before you can do anything with an OpenStack cloud, you need to authenticate yourself with the identity service, "Keystone".
38
+ * All following examples assume that `@connection_params` is a hash of valid connection information for an OpenStack cloud.
39
+ * The `:openstack_username` and `:openstack_api_key` keys must map to a valid user/password combination in Keystone.
40
+ * If you don't know what domain your user belongs to, chances are it's the `default` domain. By default, all users are a member of the `default` domain unless otherwise specified.
41
+
42
+ Connection parameters:
43
+
44
+ ```ruby
45
+ @connection_params = {
46
+ openstack_auth_url: "http://devstack.test:5000/v3/auth/tokens",
47
+ openstack_username: "admin",
48
+ openstack_api_key: "password",
49
+ openstack_project_name: "admin",
50
+ openstack_domain_id: "default"
51
+ }
52
+ ```
53
+
54
+ If you're using Keystone V2, you don't need to supply domain details but ensure the `openstack_auth_url` parameter references the correct endpoint.
55
+
56
+ ```ruby
57
+ @connection_params = {
58
+ openstack_auth_url: "http://devstack.test:5000/v2.0/tokens"
59
+ openstack_username: "admin",
60
+ openstack_api_key: "password",
61
+ openstack_project_name: "admin"
62
+ }
63
+ ```
64
+
65
+ If you're not sure whether your OpenStack cloud uses Keystone V2 or V3 then you can find out by logging into the dashboard (Horizon) and navigating to "Access & Security" under the "Project" section. Select "API Access" and find the line for the Identity Service. If the endpoint has "v3" in it, you're on Keystone V3, if it has "v2" then (surprise) you're on Keystone V2.
66
+
67
+ If you need a version of OpenStack to test against, get youself a copy of [DevStack](http://docs.openstack.org/developer/devstack/).
68
+
69
+ ### Networking Gotcha
70
+
71
+ Note that tenants (aka projects) in OpenStack usually require that you create a default gateway router in order to allow external access to your instances.
72
+
73
+ The exception is if you're using Nova (and not Neutron) for your instance networking. If you're using Neutron, you'll want to [set up your default gateway](https://github.com/fog/fog-openstack/blob/usage_doc/README.md#networking-neutron) before you try to give instances public addresses (aka floating IPs).
74
+
75
+ ### Compute (Nova)
76
+
77
+ Initialise a connection to the compute service:
78
+
79
+ ```ruby
80
+ compute = Fog::Compute::OpenStack.new(@connection_params)
81
+ ```
82
+
83
+ Get a list of available images for use with booting new instances:
84
+
85
+ ```ruby
86
+ p compute.images
87
+ # => <Fog::Compute::OpenStack::Images
88
+ # filters={},
89
+ # server=nil
90
+ # [
91
+ # <Fog::Compute::OpenStack::Image
92
+ # id="57a67f8a-7bae-4578-b684-b9b4dcd48d7f",
93
+ # ...
94
+ # >
95
+ # ]
96
+ # >
97
+ ```
98
+
99
+ List available flavors so we can decide how powerful to make this instance:
100
+
101
+ ```ruby
102
+ p compute.flavors
103
+ # => <Fog::Compute::OpenStack::Flavors
104
+ # [
105
+ # <Fog::Compute::OpenStack::Flavor
106
+ # id="1",
107
+ # name="m1.tiny",
108
+ # ram=512,
109
+ # disk=1,
110
+ # vcpus=1,
111
+ # ...
112
+ # >,
113
+ # <Fog::Compute::OpenStack::Flavor
114
+ # id="2",
115
+ # name="m1.small",
116
+ # ram=2048,
117
+ # disk=20,
118
+ # vcpus=1,
119
+ # ...
120
+ # >,
121
+ # ...
122
+
123
+ ```
124
+
125
+ Now we know the `id` numbers of a valid image and a valid flavor, we can instantiate an instance:
126
+
127
+ ```ruby
128
+ flavor = compute.flavors[0]
129
+ image = compute.images[0]
130
+ instance = compute.servers.create name: 'test',
131
+ image_ref: image.id,
132
+ flavor_ref: flavor.id
133
+
134
+ # Optionally, wait for the instance to provision before continuing
135
+ instance.wait_for { ready? }
136
+ # => {:duration=>17.359134}
137
+
138
+ p instance
139
+ # => <Fog::Compute::OpenStack::Server
140
+ # id="63633125-26b5-4fe1-a909-0f44d1ab3337",
141
+ # instance_name=nil,
142
+ # addresses={"public"=>[{"OS-EXT-IPS-MAC:mac_addr"=>"fa:16:3e:f4:75:ab", "version"=>4, "addr"=>"1.2.3.4", "OS-EXT-IPS:type"=>"fixed"}]},
143
+ # flavor={"id"=>"2"},
144
+ # host_id="f5ea01262720d02e886508bc4fa994782c516557d232c72aeb79638e",
145
+ # image={"id"=>"57a67f8a-7bae-4578-b684-b9b4dcd48d7f"},
146
+ # name="test",
147
+ # personality=nil,
148
+ # progress=0,
149
+ # accessIPv4="",
150
+ # accessIPv6="",
151
+ # availability_zone="nova",
152
+ # user_data_encoded=nil,
153
+ # state="ACTIVE",
154
+ # created=2016-03-07 08:07:36 UTC,
155
+ # updated=2016-03-07 08:07:52 UTC,
156
+ # tenant_id="06a9a90c60074cdeae5f7fdd0048d9ac"
157
+ # ...
158
+ # >
159
+ ```
160
+
161
+ And destroy it when we're done:
162
+
163
+ ```ruby
164
+ instance.destroy
165
+ # => true
166
+ ```
167
+
168
+ You'll probably need your instances to be accessible via SSH. [Learn more about SSH keypairs](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/).
169
+
170
+ Allow TCP traffic through port 22:
171
+
172
+ ```ruby
173
+ security_group = compute.security_groups.create name: "Test SSH",
174
+ description: "Allow access to port 22"
175
+ # => <Fog::Compute::OpenStack::SecurityGroup
176
+ # id="e5d53d00-b3f9-471a-b90f-985694b966ed",
177
+ # name="Test SSH",
178
+ # description="Allow access to port 22",
179
+ # security_group_rules= <Fog::Compute::OpenStack::SecurityGroupRules
180
+ # [
181
+
182
+ # ]
183
+ # >,
184
+ # tenant_id="06a9a90c60074cdeae5f7fdd0048d9ac"
185
+ # >
186
+
187
+ compute.security_group_rules.create parent_group_id: security_group.id,
188
+ ip_protocol: "tcp",
189
+ from_port: 22,
190
+ to_port: 22
191
+
192
+ key_pair = compute.key_pairs.create name: "My Public Key",
193
+ public_key: "/full/path/to/ssh.pub"
194
+ # => <Fog::Compute::OpenStack::KeyPair
195
+ # name="My Public Key",
196
+ # ...
197
+ # user_id="20746f49211e4037a91269df6a3fbf7b",
198
+ # id=nil
199
+ # >
200
+ ```
201
+
202
+ Now create a new server using the security group and keypair we created:
203
+
204
+ ```ruby
205
+ instance = compute.servers.create name: "Test 2",
206
+ image_ref: image.id,
207
+ flavor_ref: flavor.id,
208
+ key_name: key_pair.name,
209
+ security_groups: security_group
210
+ # => <Fog::Compute::OpenStack::Server
211
+ # id="e18ebdfb-e5f5-4a45-929f-4cc9926dc2c7",
212
+ # name="Test 2",
213
+ # state="ACTIVE",
214
+ # tenant_id="06a9a90c60074cdeae5f7fdd0048d9ac",
215
+ # key_name="My Public Key",
216
+ # >
217
+ # (some data omitted for brevity)
218
+ ```
219
+
220
+ Finally, assign a floating IP address to make this instance sit under a world-visible public IP address:
221
+
222
+ ```ruby
223
+ pool_name = compute.addresses.get_address_pools[0]['name']
224
+ floating_ip_address = compute.addresses.create pool: pool_name
225
+ instance.associate_address floating_ip_address.ip
226
+
227
+ p floating_ip_address
228
+ # => <Fog::Compute::OpenStack::Address
229
+ # id="54064324-ce7d-448d-9753-94497b29dc91",
230
+ # ip="1.2.3.4",
231
+ # pool="external",
232
+ # fixed_ip="192.168.0.96",
233
+ # instance_id="e18ebdfb-e5f5-4a45-929f-4cc9926dc2c7"
234
+ # >
235
+ ```
236
+
237
+ Now you can SSH into the instance:
238
+
239
+ ```
240
+ $ ssh cirros@1.2.3.4
241
+ The authenticity of host '1.2.3.4 (1.2.3.4)' can't be established.
242
+ RSA key fingerprint is SHA256:cB0L/owUtcHsMhFhsuSZXxK4oRg/uqP/6IriUomQnQQ.
243
+ Are you sure you want to continue connecting (yes/no)? yes
244
+ Warning: Permanently added '1.2.3.4' (RSA) to the list of known hosts.
245
+ $ pwd
246
+ /home/cirros
247
+ ```
248
+
249
+ ### Volume (Cinder)
250
+
251
+ Create and attach a volume to a running instance:
252
+
253
+ ```ruby
254
+ compute = Fog::Compute::OpenStack.new(@connection_params)
255
+
256
+ volume = compute.volumes.create name: "Test",
257
+ description: "Testing",
258
+ size: 1
259
+ # => <Fog::Compute::OpenStack::Volume
260
+ # id="4a212986-c6b6-4a93-8319-c6a98e347750",
261
+ # name="Test",
262
+ # description="Testing",
263
+ # size=1,
264
+ # availability_zone="Production",
265
+ # created_at="2016-03-07T13:40:43.914063",
266
+ # attachments=[{}]
267
+ # >
268
+
269
+ flavor = compute.flavors[3]
270
+ image = compute.images[0]
271
+ instance = compute.servers.create name: "test",
272
+ image_ref: image.id,
273
+ flavor_ref: flavor.id
274
+ instance.wait_for { ready? }
275
+
276
+ volume.reload
277
+
278
+ instance.attach_volume(volume.id, "/dev/vdb")
279
+ ```
280
+
281
+ Detach volume and create a snapshot:
282
+
283
+ ```ruby
284
+ instance.detach_volume(volume.id)
285
+ volume.reload
286
+
287
+ compute.snapshots.create volume_id: volume.id,
288
+ name: "test",
289
+ description: "test"
290
+ # => <Fog::Compute::OpenStack::Snapshot
291
+ # id="7a8c9192-25ee-4364-be91-070b7a6d9855",
292
+ # name="test",
293
+ # description="test",
294
+ # volume_id="4a212986-c6b6-4a93-8319-c6a98e347750",
295
+ # status="creating",
296
+ # size=1,
297
+ # created_at="2016-03-07T13:47:11.543814"
298
+ # >
299
+ ```
300
+
301
+ Destroy a volume:
302
+ ```ruby
303
+ volume.destroy
304
+ # => true
305
+ ```
306
+
307
+ ### Image (Glance)
308
+
309
+ Create Glance image from URL:
310
+
311
+ ```ruby
312
+
313
+ image = Fog::Image::OpenStack.new(@connection_params)
314
+
315
+ cirros_location = "http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img"
316
+
317
+ image.images.create name: "cirros",
318
+ disk_format: "qcow2",
319
+ container_format: "bare",
320
+ location: cirros_location
321
+ # => <Fog::Image::OpenStack::V2::Image
322
+ # id="4beedb46-e32f-4ef3-a87b-7f1234294dc1",
323
+ # name="cirros",
324
+ # visibility="private",
325
+ # tags=[],
326
+ # self="/v2/images/4beedb46-e32f-4ef3-a87b-7f1234294dc1",
327
+ # size=nil,
328
+ # disk_format="qcow2",
329
+ # container_format="bare",
330
+ # id="4beedb46-e32f-4ef3-a87b-7f1234294dc1",
331
+ # checksum=nil,
332
+ # self="/v2/images/4beedb46-e32f-4ef3-a87b-7f1234294dc1",
333
+ # file="/v2/images/4beedb46-e32f-4ef3-a87b-7f1234294dc1/file",
334
+ # min_disk=0,
335
+ # created_at="2016-03-07T14:28:10Z",
336
+ # updated_at="2016-03-07T14:28:10Z",
337
+ # protected=false,
338
+ # status="queued",
339
+ # >
340
+
341
+ ```
342
+
343
+ Create Glance image from file:
344
+
345
+ ```ruby
346
+ cirros_location = "http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img"
347
+ image_out = File.open("/tmp/cirros-image-#{SecureRandom.hex}", 'wb')
348
+
349
+ streamer = lambda do |chunk, _, _|
350
+ image_out.write chunk
351
+ end
352
+
353
+ Excon.get cirros_location, response_block: streamer
354
+ image_out.close
355
+
356
+ image.images.create name: "cirros",
357
+ disk_format: "qcow2",
358
+ container_format: "bare",
359
+ location: image_out.path
360
+
361
+ ```
362
+
363
+ Destroy image:
364
+
365
+ ```ruby
366
+ cirros = image.images.get("4beedb46-e32f-4ef3-a87b-7f1234294dc1")
367
+ cirros.destroy
368
+ ```
369
+
370
+ ### Identity (Keystone)
371
+
372
+ List domains (Keystone V3 only):
373
+
374
+ ```ruby
375
+ identity = Fog::Identity::OpenStack.new(@connection_params)
376
+
377
+ identity.domains
378
+ # => <Fog::Identity::OpenStack::V3::Domains
379
+ # [
380
+ # <Fog::Identity::OpenStack::V3::Domain
381
+ # id="default",
382
+ # description="",
383
+ # enabled=true,
384
+ # name="Default",
385
+ # >
386
+ # ]
387
+ # >
388
+ ```
389
+
390
+ List projects (aka tenants):
391
+
392
+ ```ruby
393
+ identity.projects
394
+ # => <Fog::Identity::OpenStack::V3::Projects
395
+ # [
396
+ # <Fog::Identity::OpenStack::V3::Project
397
+ # id="008e5537d3424295a03560abc923693c",
398
+ # domain_id="default",
399
+ # description="Project 1",
400
+ # enabled=true,
401
+ # name="project_1",
402
+ # >,
403
+ # ...
404
+ # ]
405
+
406
+ # On Keystone V2
407
+ identity.tenants
408
+ # => <Fog::Identity::OpenStack::V2::Tenants
409
+ # [ ... ]
410
+ ```
411
+
412
+ List users:
413
+
414
+ ```ruby
415
+ identity.users
416
+ # => <Fog::Identity::OpenStack::V3::Users
417
+ # [ ... ]
418
+ ```
419
+
420
+ Create/destroy new user:
421
+
422
+ ```ruby
423
+ project_id = identity.projects[0].id
424
+
425
+ user = identity.users.create name: "test",
426
+ project_id: project_id,
427
+ email: "test@test.com",
428
+ password: "test"
429
+ # => <Fog::Identity::OpenStack::V3::User
430
+ # id="474a59153ebd4e709938e5e9b614dc57",
431
+ # default_project_id=nil,
432
+ # description=nil,
433
+ # domain_id="default",
434
+ # email="test@test.com",
435
+ # enabled=true,
436
+ # name="test",
437
+ # password="test"
438
+ # >
439
+
440
+ user.destroy
441
+ # => true
442
+ ```
443
+
444
+ Create/destroy new tenant:
445
+
446
+ ```ruby
447
+
448
+ project = identity.projects.create name: "test",
449
+ description: "test"
450
+ # => <Fog::Identity::OpenStack::V3::Project
451
+ # id="423559128a7249f2973cdb7d5d581c4d",
452
+ # domain_id="default",
453
+ # description="test",
454
+ # enabled=true,
455
+ # name="test",
456
+ # parent_id=nil,
457
+ # subtree=nil,
458
+ # parents=nil
459
+ # >
460
+
461
+ project.destroy
462
+ # => true
463
+ ```
464
+
465
+ Grant user role on tenant and revoke it:
466
+
467
+ ```ruby
468
+ role = identity.roles.select{|role| role.name == "_member_"}[0]
469
+ # => <Fog::Identity::OpenStack::V3::Role
470
+ # id="9fe2ff9ee4384b1894a90878d3e92bab",
471
+ # name="_member_",
472
+ # >
473
+
474
+ project.grant_role_to_user(role.id, user.id)
475
+
476
+ project.revoke_role_from_user(role.id, user.id)
477
+ ```
478
+
479
+ ### Networking (Neutron)
480
+
481
+ Set up a project's public gateway (needed for external access):
482
+
483
+ ```ruby
484
+
485
+ identity = Fog::Identity::OpenStack.new(@connection_params)
486
+
487
+ tenants = identity.projects.select do |project|
488
+ project.name == @connection_params[:openstack_project_name]
489
+ end
490
+
491
+ tenant_id = tenants[0].id
492
+
493
+ neutron = Fog::Network::OpenStack.new(@connection_params)
494
+
495
+ network = neutron.networks.create name: "default",
496
+ tenant_id: tenant_id
497
+
498
+ subnet = network.subnets.create name: "default",
499
+ cidr: "192.168.0.0/24",
500
+ network_id: network.id,
501
+ ip_version: 4,
502
+ dns_nameservers: ["8.8.8.8", "8.8.4.4"],
503
+ tenant_id: tenant_id
504
+
505
+ external_network = neutron.networks.select(&:router_external)[0]
506
+
507
+ router = neutron.routers.create name: 'default',
508
+ tenant_id: tenant_id,
509
+ external_gateway_info: external_network.id
510
+
511
+ neutron.add_router_interface router.id, subnet.id
512
+
513
+ ```
514
+
515
+ ### Further Reading
516
+
517
+ * See [the documentation directory](https://github.com/fog/fog-openstack/tree/master/lib/fog/openstack/docs) for more examples.
518
+ * Read the [OpenStack API documentation](http://developer.openstack.org/api-ref.html).
519
+ * Also, remember that reading the code itself is the best way to educate yourself on how best to interact with this gem.
26
520
 
27
521
  ## Development
28
522