fog-google 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.fog.example +27 -0
  3. data/.rubocop.yml +10 -0
  4. data/.travis.yml +4 -3
  5. data/README.md +6 -18
  6. data/examples/bootstrap.rb +0 -1
  7. data/examples/network.rb +24 -4
  8. data/examples/precreated_client.rb +13 -0
  9. data/lib/fog/compute/google.rb +14 -2
  10. data/lib/fog/compute/google/models/firewall.rb +9 -0
  11. data/lib/fog/compute/google/models/instance_group.rb +15 -1
  12. data/lib/fog/compute/google/models/network.rb +10 -1
  13. data/lib/fog/compute/google/models/server.rb +6 -0
  14. data/lib/fog/compute/google/models/snapshots.rb +9 -3
  15. data/lib/fog/compute/google/models/subnetwork.rb +5 -0
  16. data/lib/fog/compute/google/requests/insert_instance_group.rb +9 -2
  17. data/lib/fog/compute/google/requests/insert_server.rb +40 -24
  18. data/lib/fog/compute/google/requests/list_snapshots.rb +3 -2
  19. data/lib/fog/compute/google/requests/update_firewall.rb +43 -0
  20. data/lib/fog/dns/google.rb +11 -2
  21. data/lib/fog/google/monitoring.rb +11 -2
  22. data/lib/fog/google/pubsub.rb +11 -2
  23. data/lib/fog/google/requests/pubsub/create_subscription.rb +1 -1
  24. data/lib/fog/google/sql.rb +11 -2
  25. data/lib/fog/google/version.rb +1 -1
  26. data/lib/fog/storage/google_json.rb +11 -2
  27. data/lib/fog/storage/google_json/models/files.rb +0 -4
  28. data/lib/fog/storage/google_json/requests/get_bucket.rb +0 -2
  29. data/tasks/console.rake +7 -0
  30. data/tasks/test.rake +1 -0
  31. data/test/integration/compute/test_compute_addresses_collection.rb +1 -1
  32. data/test/integration/compute/test_compute_networks_collection.rb +78 -0
  33. metadata +7 -4
  34. data/tasks/smoke.rake +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65e4868fbdd7a60000ea6a349ce4f693c39bd62c
4
- data.tar.gz: 92c1d9a1f79427c290e499896a8d454eb9d78556
3
+ metadata.gz: 10a8ac12072ce29979f949f17a52e6abe869066a
4
+ data.tar.gz: 2b605bd25340566ef987a53dd4630af3d04cddb0
5
5
  SHA512:
6
- metadata.gz: 8d14851bab45918fec8f0d4cbb48ad6768b6ddeb298e0241f4b09b7ba918615251758ec22ef2636e1d481ee84ffae8bef4952107242a722523953141b1e2f799
7
- data.tar.gz: 4236f7940f9f9d86362cd18ea0e0eccf466768f9ebcb3ae7a54d7c48bbbdfbff8139f06107f69837593cfb3a1684f5529b2c2e59b252fc1ea5f4040760d1c6cd
6
+ metadata.gz: a01b577b14ecf8c6393a2736f846e1057adefebbdae28ce999ca50868a03d2edd71d7e2363ec7c9dca30b137a64926eb3686bd9ad9c939385d27b9e1c81d4884
7
+ data.tar.gz: e3945cdfa27edeff1badc22cf32cb43dd68fbeb159673e83684e4dc539dd6a4af2f3aeca453b5fb64741c0903b18d40854dfc6b05c9c4eab348e2684dba64461
data/.fog.example ADDED
@@ -0,0 +1,27 @@
1
+ ##################################################################
2
+ # This is configuration snippet to configure Google Cloud Platform
3
+ # for fog library.
4
+ #
5
+ # 1. Copy this file into your home dir: "~/.fog":
6
+ #
7
+ # $ cat .fog.example >> ~/.fog
8
+ #
9
+ # 2. Follow instructions to generate a private key:
10
+ # https://cloud.google.com/storage/docs/authentication#generating-a-private-key
11
+ #
12
+ # 3. Edit the new file accordingly.
13
+ #
14
+ ##################################################################
15
+ # START GOOGLE CONFIG
16
+ my_google_credentials:
17
+ google_project: my-project-id
18
+ google_client_email: xxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com
19
+ google_json_key_location: /path/to/my-project-xxxxxxxxxxxx.json
20
+ # You can also provide service account credentials with `google_json_key_string` or
21
+ # with `google_key_location` and `google_key_string` for P12 private keys.
22
+ # If so, uncomment the two following lines.
23
+ # HMAC credentials follow a similar format:
24
+ #google_storage_access_key_id: GOOGXXXXXXXXXXXXXXXX
25
+ #google_storage_secret_access_key: XXXX+XXX/XXXXXXXX+XXXXXXXXXXXXXXXXXXXXX
26
+ # /END GOOGLE CONFIG
27
+ #################################################################
data/.rubocop.yml CHANGED
@@ -2,12 +2,22 @@
2
2
  Metrics/LineLength:
3
3
  Enabled: false
4
4
 
5
+ Style/ConditionalAssignment:
6
+ SingleLineConditionsOnly: true
7
+
5
8
  Style/Encoding:
6
9
  EnforcedStyle: when_needed
7
10
 
8
11
  Style/FormatString:
9
12
  Enabled: false
10
13
 
14
+ Style/RegexpLiteral:
15
+ Enabled: false
16
+
17
+ #TODO: this needs to be adressed not through the linter
18
+ Style/FrozenStringLiteralComment:
19
+ Enabled: false
20
+
11
21
  Style/HashSyntax:
12
22
  EnforcedStyle: hash_rockets
13
23
 
data/.travis.yml CHANGED
@@ -1,17 +1,18 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  sudo: false
4
+ dist: trusty
4
5
  matrix:
5
6
  fast_finish: true
6
7
  include:
7
8
  - rvm: 2.1
8
9
  - rvm: 2.2
9
- - rvm: 2.3.0
10
- - rvm: 2.3.1
10
+ - rvm: 2.3
11
11
  - rvm: 2.4.0
12
+ - rvm: 2.4.1
12
13
  - rvm: jruby-head
13
14
  allow_failures:
14
15
  - rvm: jruby-head
15
- - rvm: 2.4.0
16
+ - rvm: 2.4.1
16
17
  notifications:
17
18
  email: false
data/README.md CHANGED
@@ -67,24 +67,12 @@ $ gem install fog-google
67
67
 
68
68
  #### Credentials
69
69
 
70
- Follow the [instructions to generate a private key](https://cloud.google.com/storage/docs/authentication#generating-a-private-key). You can then create a fog credentials file at `~/.fog`, which will look something like this:
70
+ Follow the [instructions to generate a private key](https://cloud.google.com/storage/docs/authentication#generating-a-private-key). A sample credentials file can be found in `.fog.example` in this directory:
71
71
 
72
- ```
73
- my_credential:
74
- google_project: my-project
75
- google_client_email: xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com
76
- google_json_key_location: /path/to/my-project-xxxxxxxxxxxx.json
77
- ```
78
-
79
- You can also provide service account credentials with `google_json_key_string` or with `google_key_location` and `google_key_string` for P12 private keys.
72
+ cat .fog.example >> ~/.fog # appends the sample configuration
73
+ vim ~/.fog # edit file with yout config
74
+
80
75
 
81
- HMAC credentials follow a similar format:
82
-
83
- ```
84
- my_credentials:
85
- google_storage_access_key_id: GOOGXXXXXXXXXXXXXXXX
86
- google_storage_secret_access_key: XXXX+XXX/XXXXXXXX+XXXXXXXXXXXXXXXXXXXXX
87
- ```
88
76
 
89
77
  #### SSH-ing into instances
90
78
 
@@ -94,7 +82,7 @@ If you want to be able to bootstrap SSH-able instances, (using `servers.bootstra
94
82
 
95
83
  Once you've specified your credentials, you should be good to go!
96
84
  ```
97
- λ bundle exec pry
85
+ $ bundle exec pry
98
86
  [1] pry(main)> require 'fog/google'
99
87
  => true
100
88
  [2] pry(main)> connection = Fog::Compute::Google.new
@@ -106,4 +94,4 @@ Once you've specified your credentials, you should be good to go!
106
94
 
107
95
  ## Contributing
108
96
 
109
- See `CONTRIBUTING.md` in this repository.
97
+ See `CONTRIBUTING.md` in this repository.
@@ -10,7 +10,6 @@ def test
10
10
  connection = Fog::Compute.new(:provider => "Google")
11
11
 
12
12
  server = connection.servers.bootstrap
13
- server.wait_for { sshable? }
14
13
 
15
14
  raise "Could not bootstrap sshable server." unless server.ssh("whoami")
16
15
  raise "Could not delete server." unless server.destroy
data/examples/network.rb CHANGED
@@ -1,11 +1,25 @@
1
+ # All examples presume that you have a ~/.fog credentials file set up.
2
+ # More info on it can be found here: http://fog.io/about/getting_started.html
3
+
4
+ require "bundler"
5
+ Bundler.require(:default, :development)
6
+ # Uncomment this if you want to make real requests to GCE (you _will_ be billed!)
7
+ # WebMock.disable!
8
+
1
9
  def test
2
10
  connection = Fog::Compute.new(:provider => "Google")
3
11
 
4
- # we create a new private network
5
- connection.insert_network("my-private-network", "10.240.0.0/16")
12
+ puts "Creating a new private network..."
13
+ puts "---------------------------------"
14
+ network = connection.networks.create(
15
+ :name => "test-private-network",
16
+ :ipv4_range => "10.240.0.0/16"
17
+ )
6
18
 
7
19
  name = "fog-smoke-test-#{Time.now.to_i}"
8
20
 
21
+ puts "Creating a disk for an instance..."
22
+ puts "---------------------------------"
9
23
  disk = connection.disks.create(
10
24
  :name => name,
11
25
  :size_gb => 10,
@@ -15,6 +29,8 @@ def test
15
29
 
16
30
  disk.wait_for { disk.ready? }
17
31
 
32
+ puts "Spinning up an instance with private network config..."
33
+ puts "------------------------------------------------------"
18
34
  server = connection.servers.create(
19
35
  :name => name,
20
36
  :disks => [disk],
@@ -22,14 +38,18 @@ def test
22
38
  :zone_name => "us-central1-a",
23
39
  :private_key_path => File.expand_path("~/.ssh/id_rsa"),
24
40
  :public_key_path => File.expand_path("~/.ssh/id_rsa.pub"),
25
- :network => "my-private-network",
41
+ :network => network,
26
42
  :external_ip => false,
27
- :user => ENV["USER"])
43
+ :username => ENV["USER"]
44
+ )
28
45
 
29
46
  # The network won't have any firewall rules, so we won't be able to ssh in.
30
47
  server.wait_for { ready? }
31
48
 
32
49
  raise "Could not delete server." unless server.destroy
50
+ raise "Could not delete network." unless network.destroy
33
51
  rescue StandardError => e
34
52
  p e.message
35
53
  end
54
+
55
+ test
@@ -1,3 +1,14 @@
1
+ # All examples presume that you have a ~/.fog credentials file set up.
2
+ # More info on it can be found here: http://fog.io/about/getting_started.html
3
+
4
+ require "bundler"
5
+ Bundler.require(:default, :development)
6
+ # Uncomment this if you want to make real requests to GCE (you _will_ be billed!)
7
+ # WebMock.disable!
8
+
9
+ # This example shows how to work with fog using a pre-created Google API client
10
+ # with specific parameters, should you want to for any reason.
11
+
1
12
  def test
2
13
  client = Google::APIClient.new(:application_name => "supress")
3
14
  connection = Fog::Compute.new(:provider => "Google", :google_client => client)
@@ -9,3 +20,5 @@ def test
9
20
  p e.message
10
21
  end
11
22
  end
23
+
24
+ test
@@ -5,8 +5,18 @@ module Fog
5
5
  autoload :Real, File.expand_path("../google/real", __FILE__)
6
6
 
7
7
  requires :google_project
8
- recognizes :app_name, :app_version, :google_client_email, :google_key_location, :google_key_string,
9
- :google_client, :google_json_key_location, :google_json_key_string, :google_extra_global_projects
8
+ recognizes(
9
+ :app_name,
10
+ :app_version,
11
+ :google_client,
12
+ :google_client_email,
13
+ :google_client_options,
14
+ :google_extra_global_projects,
15
+ :google_key_location,
16
+ :google_key_string,
17
+ :google_json_key_location,
18
+ :google_json_key_string
19
+ )
10
20
 
11
21
  GOOGLE_COMPUTE_API_VERSION = "v1"
12
22
  GOOGLE_COMPUTE_BASE_URL = "https://www.googleapis.com/compute/"
@@ -16,6 +26,7 @@ module Fog
16
26
  https://www.googleapis.com/auth/cloud-platform)
17
27
  GOOGLE_COMPUTE_DEFAULT_NETWORK = "default"
18
28
  RUNNING = "RUNNING".freeze
29
+ PROVISIONING = "PROVISIONING".freeze
19
30
 
20
31
  request_path "fog/compute/google/requests"
21
32
  request :add_backend_service_backends
@@ -90,6 +101,7 @@ module Fog
90
101
  request :insert_backend_service
91
102
  request :insert_disk
92
103
  request :insert_firewall
104
+ request :update_firewall
93
105
  request :insert_forwarding_rule
94
106
  request :insert_global_forwarding_rule
95
107
  request :insert_http_health_check
@@ -28,6 +28,15 @@ module Fog
28
28
  reload
29
29
  end
30
30
 
31
+ def update
32
+ requires :identity, :allowed, :network
33
+
34
+ data = service.update_firewall(identity, allowed, network, attributes)
35
+ operation = Fog::Compute::Google::Operations.new(:service => service).get(data.body["name"])
36
+ operation.wait_for { !pending? }
37
+ reload
38
+ end
39
+
31
40
  def destroy(async = true)
32
41
  requires :identity
33
42
 
@@ -11,6 +11,7 @@ module Fog
11
11
  attribute :fingerprint
12
12
  attribute :namedPorts
13
13
  attribute :network
14
+ attribute :subnetwork
14
15
  attribute :self_link, :aliases => "selfLink"
15
16
  attribute :size
16
17
  attribute :zone, :aliases => :zone_name
@@ -18,7 +19,12 @@ module Fog
18
19
  def save
19
20
  requires :name, :zone
20
21
 
21
- service.insert_instance_group(name, zone)
22
+ options = {
23
+ "network" => network_name,
24
+ "subnetwork" => subnetwork_name
25
+ }
26
+
27
+ service.insert_instance_group(name, zone, options)
22
28
  end
23
29
 
24
30
  def destroy(_async = true)
@@ -60,6 +66,14 @@ module Fog
60
66
  zone.nil? ? nil : zone.split("/")[-1]
61
67
  end
62
68
 
69
+ def network_name
70
+ network.nil? ? nil : network.split("/")[-1]
71
+ end
72
+
73
+ def subnetwork_name
74
+ subnetwork.nil? ? nil : subnetwork.split("/")[-1]
75
+ end
76
+
63
77
  private
64
78
 
65
79
  def format_instance_list(instance_list)
@@ -21,7 +21,9 @@ module Fog
21
21
 
22
22
  data = service.insert_network(identity, ipv4_range, attributes)
23
23
  operation = Fog::Compute::Google::Operations.new(:service => service).get(data.body["name"])
24
- operation.wait_for { !pending? }
24
+ # Since network has no "state" we can query, we have to wait for the operation to finish
25
+ # TODO: change back to async when there's a proper state API
26
+ operation.wait_for { ready? }
25
27
  reload
26
28
  end
27
29
 
@@ -33,6 +35,13 @@ module Fog
33
35
  operation.wait_for { ready? } unless async
34
36
  operation
35
37
  end
38
+
39
+ # Returns a ready API structure for insert_instance, used in insert_server request.
40
+ def get_as_interface_config(access_config = nil)
41
+ network_interface = { "network" => self_link }
42
+ network_interface["accessConfigs"] = [access_config] if access_config
43
+ network_interface
44
+ end
36
45
  end
37
46
  end
38
47
  end
@@ -26,6 +26,7 @@ module Fog
26
26
  # These attributes are not available in the representation of an 'instance' returned by the GCE API.
27
27
  # They are useful only for the create process
28
28
  attribute :network, :aliases => "network"
29
+ attribute :subnetwork, :aliases => "subnetwork"
29
30
  attribute :external_ip, :aliases => "externalIP"
30
31
  attribute :auto_restart
31
32
  attribute :on_host_maintenance
@@ -198,6 +199,10 @@ module Fog
198
199
  Fog::Compute::Google::Operations.new(:service => service).get(data.body["name"], data.body["zone"])
199
200
  end
200
201
 
202
+ def provisioning?
203
+ state == PROVISIONING
204
+ end
205
+
201
206
  def ready?
202
207
  state == RUNNING
203
208
  end
@@ -251,6 +256,7 @@ module Fog
251
256
  "machineType" => machine_type,
252
257
  "networkInterfaces" => network_interfaces,
253
258
  "network" => network,
259
+ "subnetwork" => subnetwork,
254
260
  "externalIp" => external_ip,
255
261
  "disks" => disks,
256
262
  "metadata" => metadata,
@@ -5,9 +5,15 @@ module Fog
5
5
  model Fog::Compute::Google::Snapshot
6
6
 
7
7
  def all
8
- data = service.list_snapshots
9
- snapshots = data.body["items"] || []
10
- load(snapshots)
8
+ items = []
9
+ next_page_token = nil
10
+ loop do
11
+ data = service.list_snapshots(nil, next_page_token)
12
+ items.concat(data.body["items"])
13
+ next_page_token = data.body["nextPageToken"]
14
+ break if next_page_token.nil? || next_page_token.empty?
15
+ end
16
+ load(items)
11
17
  end
12
18
 
13
19
  def get(snap_id)
@@ -36,6 +36,11 @@ module Fog
36
36
  operation
37
37
  end
38
38
 
39
+ def update_interface_config(network_interface)
40
+ network_interface["subnetwork"] = self_link if network_interface
41
+ network_interface
42
+ end
43
+
39
44
  def reload
40
45
  requires :identity, :region
41
46
 
@@ -18,10 +18,17 @@ module Fog
18
18
  id = Fog::Mock.random_numbers(19).to_s
19
19
 
20
20
  body = {
21
- "name" => group_name,
22
- "network" => "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/global/networks/default"
21
+ "name" => group_name
23
22
  }
23
+
24
24
  body["description"] = options["description"] if options["description"]
25
+ network_name = options["network"] ? options["network"].split("/")[-1] : GOOGLE_COMPUTE_DEFAULT_NETWORK
26
+ body["network"] = "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/global/networks/#{network_name}"
27
+
28
+ unless options["subnetwork"].nil?
29
+ subnetwork_name = options["subnetwork"].split("/")[-1]
30
+ body["subnetwork"] = "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/regions/#{@region}/subnetworks/#{subnetwork_name}"
31
+ end
25
32
 
26
33
  request(api_method, parameters, body)
27
34
  end
@@ -110,6 +110,44 @@ module Fog
110
110
  disks
111
111
  end
112
112
 
113
+ def handle_networks(options, region_name)
114
+ # Only one access config, ONE_TO_ONE_NAT, is supported per instance.
115
+ # If there are no accessConfigs specified, then this instance will have no external internet access.
116
+ access_config = { "type" => "ONE_TO_ONE_NAT", "name" => "External NAT" }
117
+ # If natIP is undefined VM will get an IP from a shared ephemeral IP address pool
118
+ if options.key? "externalIp"
119
+ access_config["natIP"] = options.delete "externalIp"
120
+ # If :external_ip is set to 'false', do not allow _any_ external networking
121
+ access_config = nil if access_config["natIP"] == false
122
+ end
123
+
124
+ # If no networking options are specified, assume default network
125
+ if options.key? "network"
126
+ network = options.delete "network"
127
+ else
128
+ network = GOOGLE_COMPUTE_DEFAULT_NETWORK
129
+ end
130
+
131
+ # Objectify the network if needed
132
+ unless network.is_a?(Network)
133
+ network = networks.get(network)
134
+ end
135
+
136
+ network_interfaces = network.get_as_interface_config(access_config)
137
+
138
+ if options.key? "subnetwork"
139
+ subnetwork = options.delete "subnetwork"
140
+ # Objectify the subnetwork if needed
141
+ unless subnetwork.is_a?(Subnetwork)
142
+ subnetwork = subnetworks.get(subnetwork, region_name)
143
+ end
144
+ network_interfaces = subnetwork.update_interface_config(network_interfaces)
145
+ end
146
+
147
+ # Return a networkInterfaces array
148
+ [network_interfaces]
149
+ end
150
+
113
151
  def format_metadata(metadata)
114
152
  { "items" => metadata.map { |k, v| { "key" => k, "value" => v } } }
115
153
  end
@@ -170,7 +208,7 @@ module Fog
170
208
  # more information.
171
209
  # @return [Excon::Response] response object that represents the result.
172
210
  def insert_server(server_name, zone_name, options = {}, *deprecated_args)
173
- if deprecated_args.length > 0 || !options.is_a?(Hash)
211
+ if !deprecated_args.empty? || !options.is_a?(Hash)
174
212
  raise ArgumentError.new "Too many parameters specified. This may be the cause of code written for an outdated"\
175
213
  " version of fog. Usage: server_name, zone_name, [options]"
176
214
  end
@@ -182,28 +220,6 @@ module Fog
182
220
  body_object = { :name => server_name }
183
221
 
184
222
  body_object["machineType"] = @api_url + @project + "/zones/#{zone_name}/machineTypes/#{options.delete 'machineType'}"
185
- network = nil
186
- if options.key? "network"
187
- network = options.delete "network"
188
- else
189
- network = GOOGLE_COMPUTE_DEFAULT_NETWORK
190
- end
191
-
192
- # ExternalIP is default value for server creation
193
- access_config = { "type" => "ONE_TO_ONE_NAT", "name" => "External NAT" }
194
- # leave natIP undefined to use an IP from a shared ephemeral IP address pool
195
- if options.key? "externalIp"
196
- access_config["natIP"] = options.delete "externalIp"
197
- # If set to 'false', that would mean user does no want to allocate an external IP
198
- access_config = nil if access_config["natIP"] == false
199
- end
200
-
201
- networkInterfaces = []
202
- unless network.nil?
203
- networkInterface = { "network" => @api_url + @project + "/global/networks/#{network}" }
204
- networkInterface["accessConfigs"] = [access_config] if access_config
205
- networkInterfaces << networkInterface
206
- end
207
223
 
208
224
  scheduling = {
209
225
  "automaticRestart" => false,
@@ -235,7 +251,7 @@ module Fog
235
251
  end
236
252
 
237
253
  # TODO: add other networks
238
- body_object["networkInterfaces"] = networkInterfaces
254
+ body_object["networkInterfaces"] = handle_networks(options, get_zone(zone_name).body["region"].split("/")[-1])
239
255
 
240
256
  if options["disks"].nil? || options["disks"].empty?
241
257
  raise ArgumentError.new "Empty value for field 'disks'. Boot disk must be specified"
@@ -8,11 +8,12 @@ module Fog
8
8
  end
9
9
 
10
10
  class Real
11
- def list_snapshots(project = nil)
11
+ def list_snapshots(project = nil, next_page_token = nil)
12
12
  api_method = @compute.snapshots.list
13
13
  project = @project if project.nil?
14
14
  parameters = {
15
- "project" => project
15
+ "project" => project,
16
+ "pageToken" => next_page_token
16
17
  }
17
18
 
18
19
  request(api_method, parameters)
@@ -0,0 +1,43 @@
1
+ module Fog
2
+ module Compute
3
+ class Google
4
+ class Mock
5
+ def update_firewall(_firewall_name, _allowed, _network = GOOGLE_COMPUTE_DEFAULT_NETWORK, _options = {})
6
+ Fog::Mock.not_implemented
7
+ end
8
+ end
9
+
10
+ class Real
11
+ def update_firewall(firewall_name, allowed, network = GOOGLE_COMPUTE_DEFAULT_NETWORK, options = {})
12
+ unless network.start_with? "http"
13
+ network = "#{@api_url}#{@project}/global/networks/#{network}"
14
+ end
15
+
16
+ api_method = @compute.firewalls.update
17
+ parameters = {
18
+ "project" => @project,
19
+ "firewall" => firewall_name
20
+ }
21
+ body_object = {
22
+ "allowed" => allowed,
23
+ "network" => network
24
+ }
25
+ unless options[:description].nil?
26
+ body_object["description"] = options[:description]
27
+ end
28
+ unless options[:source_ranges].nil? || options[:source_ranges].empty?
29
+ body_object["sourceRanges"] = options[:source_ranges]
30
+ end
31
+ unless options[:source_tags].nil? || options[:source_tags].empty?
32
+ body_object["sourceTags"] = options[:source_tags]
33
+ end
34
+ unless options[:target_tags].nil? || options[:target_tags].empty?
35
+ body_object["targetTags"] = options[:target_tags]
36
+ end
37
+
38
+ request(api_method, parameters, body_object)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -5,8 +5,17 @@ module Fog
5
5
  autoload :Real, File.expand_path("../google/real", __FILE__)
6
6
 
7
7
  requires :google_project
8
- recognizes :app_name, :app_version, :google_client_email, :google_key_location, :google_key_string,
9
- :google_client, :google_json_key_location, :google_json_key_string
8
+ recognizes(
9
+ :app_name,
10
+ :app_version,
11
+ :google_client,
12
+ :google_client_email,
13
+ :google_client_options,
14
+ :google_key_location,
15
+ :google_key_string,
16
+ :google_json_key_location,
17
+ :google_json_key_string
18
+ )
10
19
 
11
20
  GOOGLE_DNS_API_VERSION = "v1"
12
21
  GOOGLE_DNS_BASE_URL = "https://www.googleapis.com/dns/"
@@ -5,8 +5,17 @@ module Fog
5
5
  autoload :Real, File.expand_path("../monitoring/real", __FILE__)
6
6
 
7
7
  requires :google_project
8
- recognizes :google_client_email, :google_key_location, :google_key_string, :google_client,
9
- :app_name, :app_version, :google_json_key_location, :google_json_key_string
8
+ recognizes(
9
+ :app_name,
10
+ :app_version,
11
+ :google_client,
12
+ :google_client_email,
13
+ :google_client_options,
14
+ :google_key_location,
15
+ :google_key_string,
16
+ :google_json_key_location,
17
+ :google_json_key_string
18
+ )
10
19
 
11
20
  GOOGLE_MONITORING_API_VERSION = "v2beta2".freeze
12
21
  GOOGLE_MONITORING_BASE_URL = "https://www.googleapis.com/cloudmonitoring/"
@@ -5,8 +5,17 @@ module Fog
5
5
  autoload :Real, File.expand_path("../pubsub/real", __FILE__)
6
6
 
7
7
  requires :google_project
8
- recognizes :google_client_email, :google_key_location, :google_key_string, :google_client,
9
- :app_name, :app_version, :google_json_key_location, :google_json_key_string
8
+ recognizes(
9
+ :app_name,
10
+ :app_version,
11
+ :google_client,
12
+ :google_client_email,
13
+ :google_client_options,
14
+ :google_json_key_location,
15
+ :google_json_key_string,
16
+ :google_key_location,
17
+ :google_key_string
18
+ )
10
19
 
11
20
  GOOGLE_PUBSUB_API_VERSION = "v1".freeze
12
21
  GOOGLE_PUBSUB_BASE_URL = "https://www.googleapis.com/pubsub".freeze
@@ -26,7 +26,7 @@ module Fog
26
26
  "topic" => (topic.is_a?(Topic) ? topic.name : topic.to_s)
27
27
  }
28
28
 
29
- unless push_config.empty?
29
+ if push_config && push_config.any?
30
30
  body["pushConfig"] = push_config
31
31
  end
32
32
 
@@ -5,8 +5,17 @@ module Fog
5
5
  autoload :Real, File.expand_path("../sql/real", __FILE__)
6
6
 
7
7
  requires :google_project
8
- recognizes :google_client_email, :google_key_location, :google_key_string, :google_client,
9
- :app_name, :app_version, :google_json_key_location, :google_json_key_string
8
+ recognizes(
9
+ :app_name,
10
+ :app_version,
11
+ :google_client,
12
+ :google_client_email,
13
+ :google_client_options,
14
+ :google_key_location,
15
+ :google_key_string,
16
+ :google_json_key_location,
17
+ :google_json_key_string
18
+ )
10
19
 
11
20
  GOOGLE_SQL_API_VERSION = "v1beta3"
12
21
  GOOGLE_SQL_BASE_URL = "https://www.googleapis.com/sql/"
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Google
3
- VERSION = "0.5.2".freeze
3
+ VERSION = "0.5.3".freeze
4
4
  end
5
5
  end
@@ -6,8 +6,17 @@ module Fog
6
6
  autoload :Utils, File.expand_path("../google_json/utils", __FILE__)
7
7
 
8
8
  requires :google_project
9
- recognizes :google_client_email, :google_key_location, :google_key_string, :google_client,
10
- :app_name, :app_version, :google_json_key_location, :google_json_key_string
9
+ recognizes(
10
+ :app_name,
11
+ :app_version,
12
+ :google_client,
13
+ :google_client_email,
14
+ :google_client_options,
15
+ :google_key_location,
16
+ :google_key_string,
17
+ :google_json_key_location,
18
+ :google_json_key_string
19
+ )
11
20
 
12
21
  # https://cloud.google.com/storage/docs/json_api/v1/
13
22
  GOOGLE_STORAGE_JSON_API_VERSION = "v1"
@@ -28,10 +28,6 @@ module Fog
28
28
  subset = dup.all
29
29
 
30
30
  subset.each_file_this_page { |f| yield f }
31
- while subset.is_truncated
32
- subset = subset.all(:marker => subset.last.key)
33
- subset.each_file_this_page { |f| yield f }
34
- end
35
31
 
36
32
  self
37
33
  end
@@ -61,13 +61,11 @@ module Fog
61
61
  response.body = {
62
62
  "CommonPrefixes" => [],
63
63
  "Contents" => truncated_contents,
64
- "IsTruncated" => truncated_contents.size != contents.size,
65
64
  "Marker" => options["marker"],
66
65
  "Name" => bucket["Name"],
67
66
  "Prefix" => options["prefix"]
68
67
  }
69
68
  if options["max-keys"] && options["max-keys"] < response.body["Contents"].length
70
- response.body["IsTruncated"] = true
71
69
  response.body["Contents"] = response.body["Contents"][0...options["max-keys"]]
72
70
  end
73
71
  else
data/tasks/console.rake CHANGED
@@ -5,6 +5,13 @@ desc "Project IRB console"
5
5
  task :console do
6
6
  require "bundler"
7
7
  Bundler.require(:default, :development)
8
+
9
+ # Reload helper to avoid resetting the environment when debugging
10
+ def reload!
11
+ files = $LOADED_FEATURES.select { |feat| feat =~ /\/fog-google\// }
12
+ files.each { |file| load file }
13
+ end
14
+
8
15
  ARGV.clear
9
16
  Pry.start
10
17
  end
data/tasks/test.rake CHANGED
@@ -3,6 +3,7 @@ require "rake/testtask"
3
3
  Rake::TestTask.new do |t|
4
4
  t.libs << "test"
5
5
  t.pattern = File.join("test", "**", "test_*.rb")
6
+ t.warning = false
6
7
  end
7
8
 
8
9
  namespace :test do
@@ -50,7 +50,7 @@ class TestComputeAddressesCollection < FogIntegrationTest
50
50
  ],
51
51
  :external_ip => my_address.address
52
52
  )
53
- my_server.wait_for { my_server.state != "PROVISIONING" }
53
+ my_server.wait_for { provisioning? }
54
54
 
55
55
  # And verify that it's correctly assigned
56
56
  assert_equal(
@@ -0,0 +1,78 @@
1
+ require "helpers/integration_test_helper"
2
+ require "securerandom"
3
+
4
+ class TestComputeNetworksCollection < FogIntegrationTest
5
+ DEFAULT_REGION = "us-central1".freeze
6
+ DEFAULT_ZONE = "us-central1-b".freeze
7
+ RESOURCE_PREFIX = "fog-test-networkscol".freeze
8
+
9
+ # Ensure we clean up any created resources
10
+ Minitest.after_run do
11
+ client = Fog::Compute::Google.new
12
+ client.networks.each { |a| a.destroy if a.name.start_with?(RESOURCE_PREFIX) }
13
+ client.servers.each { |s| s.destroy if s.name.start_with?(RESOURCE_PREFIX) }
14
+ end
15
+
16
+ def test_network_workflow
17
+ client = Fog::Compute::Google.new
18
+
19
+ my_network_name = new_resource_name
20
+ # An address can be created by specifying a name and a region
21
+ my_network = client.networks.create(
22
+ :name => my_network_name,
23
+ :ipv4_range => "10.240.#{rand(255)}.0/24"
24
+ )
25
+
26
+ assert_equal(my_network_name, my_network.name, "My network should have the provided name")
27
+
28
+ # It should also be visible when listing addresses
29
+ assert_includes(client.networks.all.map(&:name), my_network_name)
30
+
31
+ # Be aware that although the address resource is created, it might not yet
32
+ # have an ip address. You can poll until the address has been assigned.
33
+ my_network.wait_for { !my_network.ipv4_range.nil? }
34
+ assert_match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}/,
35
+ my_network.ipv4_range,
36
+ "My address's address should have a valid ipv4 address")
37
+
38
+ # Now that we have an address, we can create a server using the static ip
39
+ my_server = client.servers.create(
40
+ :name => new_resource_name,
41
+ :machine_type => "f1-micro",
42
+ :zone_name => DEFAULT_ZONE,
43
+ :disks => [
44
+ :boot => true,
45
+ :autoDelete => true,
46
+ :initializeParams => {
47
+ :sourceImage => "projects/debian-cloud/global/images/family/debian-8"
48
+ }
49
+ ],
50
+ :network => my_network
51
+ )
52
+ my_server.wait_for { provisioning? }
53
+
54
+ # We need to verify that the network has been correctly assigned
55
+ assert_equal(
56
+ my_network.self_link,
57
+ my_server.network_interfaces[0]["network"],
58
+ "My created server should have the network specified as the network"
59
+ )
60
+
61
+ # Access config needs to be correctly populated
62
+ assert_equal(
63
+ "ONE_TO_ONE_NAT",
64
+ my_server.network_interfaces[0]["accessConfigs"][0]["type"],
65
+ "Access config type matches the correct default"
66
+ )
67
+
68
+ assert_equal(
69
+ "External NAT",
70
+ my_server.network_interfaces[0]["accessConfigs"][0]["name"],
71
+ "Access config name matches the correct default"
72
+ )
73
+ end
74
+
75
+ def new_resource_name
76
+ "#{RESOURCE_PREFIX}-#{SecureRandom.uuid}"
77
+ end
78
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-google
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nat Welch
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2017-01-13 00:00:00.000000000 Z
14
+ date: 2017-06-02 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: fog-core
@@ -208,6 +208,7 @@ extensions: []
208
208
  extra_rdoc_files: []
209
209
  files:
210
210
  - ".editorconfig"
211
+ - ".fog.example"
211
212
  - ".gitignore"
212
213
  - ".hound.yml"
213
214
  - ".rubocop.yml"
@@ -440,6 +441,7 @@ files:
440
441
  - lib/fog/compute/google/requests/set_target_http_proxy_url_map.rb
441
442
  - lib/fog/compute/google/requests/start_server.rb
442
443
  - lib/fog/compute/google/requests/stop_server.rb
444
+ - lib/fog/compute/google/requests/update_firewall.rb
443
445
  - lib/fog/compute/google/requests/update_url_map.rb
444
446
  - lib/fog/compute/google/requests/validate_url_map.rb
445
447
  - lib/fog/dns/google.rb
@@ -598,7 +600,6 @@ files:
598
600
  - tasks/bundler.rake
599
601
  - tasks/console.rake
600
602
  - tasks/lint.rake
601
- - tasks/smoke.rake
602
603
  - tasks/test.rake
603
604
  - test/helpers/client_helper.rb
604
605
  - test/helpers/integration_test_helper.rb
@@ -607,6 +608,7 @@ files:
607
608
  - test/integration/compute/requests/test_compute_address_requests.rb
608
609
  - test/integration/compute/test_backend_services.rb
609
610
  - test/integration/compute/test_compute_addresses_collection.rb
611
+ - test/integration/compute/test_compute_networks_collection.rb
610
612
  - test/integration/compute/test_disk_types.rb
611
613
  - test/integration/compute/test_disks.rb
612
614
  - test/integration/compute/test_forwarding_rules.rb
@@ -725,7 +727,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
725
727
  version: '0'
726
728
  requirements: []
727
729
  rubyforge_project:
728
- rubygems_version: 2.4.5.1
730
+ rubygems_version: 2.6.10
729
731
  signing_key:
730
732
  specification_version: 4
731
733
  summary: Module for the 'fog' gem to support Google.
@@ -737,6 +739,7 @@ test_files:
737
739
  - test/integration/compute/requests/test_compute_address_requests.rb
738
740
  - test/integration/compute/test_backend_services.rb
739
741
  - test/integration/compute/test_compute_addresses_collection.rb
742
+ - test/integration/compute/test_compute_networks_collection.rb
740
743
  - test/integration/compute/test_disk_types.rb
741
744
  - test/integration/compute/test_disks.rb
742
745
  - test/integration/compute/test_forwarding_rules.rb
data/tasks/smoke.rake DELETED
@@ -1,15 +0,0 @@
1
- desc "Run smoke tests from examples directory"
2
- namespace :google do
3
- namespace :smoke do
4
- desc "Smoke tests for Google Compute Engine."
5
- task :compute do
6
- puts "These smoke tests assume you have a file at ~/.fog which has your credentials for connecting to GCE."
7
-
8
- Dir.glob("./examples/*.rb").each do |file|
9
- puts "Running #{file}:"
10
- require file
11
- test
12
- end
13
- end
14
- end
15
- end