Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subnetwork support #216

Merged
merged 18 commits into from
May 30, 2017
Merged

Subnetwork support #216

merged 18 commits into from
May 30, 2017

Conversation

Wyosotis
Copy link
Contributor

Please review this pull request which has been made for solving the issue #117

end

network_interface["accessConfigs"] = [access_config] if access_config

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.

subnetwork = subnetworks.get(subnetwork, region_name)
end

network_interface["subnetwork"] = subnetwork.get_self_link_attr()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use parentheses for method calls with no arguments.
Trailing whitespace detected.

# Extract region_name from zone_name
l = zone_name.split(/-/)
region_name = l[0] + "-" + l[1]
subnetwork = subnetworks.get(subnetwork, region_name)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.


# Objectify the subnetwork if needed
unless subnetwork.is_a? Subnetwork
# Extract region_name from zone_name

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.


if options.key? "subnetwork"
subnetwork = options.delete "subnetwork"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.

@@ -133,8 +133,26 @@ def handle_networks(options)
network = networks.get(network)
end

network_interface = { "network" => network.get_self_link_attr() }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use parentheses for method calls with no arguments.

body["description"] = options["description"] if options["description"]
network_name = options["network"] ? options["network"].split("/")[-1] : GOOGLE_COMPUTE_DEFAULT_NETWORK
body["network"] = "https://www.googleapis.com/compute/#{api_version}/projects/#{@project}/global/networks/#{network_name}"

unless options["subnetwork"].nil?
subnetwork_name = options["subnetwork"].split("/")[-1]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.

@@ -36,6 +36,10 @@ def destroy(async = true)
operation
end

def get_self_link_attr
return [self_link]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant return detected.

end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra empty line detected at class body end.

network_interface["accessConfigs"] = [access_config] if access_config
network_interface
def get_self_link_attr
return [self_link]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant return detected.

region_name = l[0] + "-" + l[1]
subnetwork = subnetworks.get(subnetwork, region_name)
end
network_interface["subnetwork"] = subnetwork.get_self_link_attr

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.

subnetwork = options.delete "subnetwork"
# Objectify the subnetwork if needed
unless subnetwork.is_a? Subnetwork
# Extract region_name from zone_name

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can run rubocop -a filename to autocleanup these.

Copy link
Member

@icco icco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty good so far.

def get_as_interface_config(access_config = nil)
network_interface = { "network" => self_link }
network_interface["accessConfigs"] = [access_config] if access_config
network_interface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way we can leave this method name the same? I'm also not entirely sure what this function is doing (or what it was doing for that matter).

Copy link
Member

@icco icco Apr 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading the code that uses this, I'm wondering if we should just delete the function and the one you replaced it with and just put the array creation in the code where it's needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if it is a good way to add subnetwork setting in the method get_as_interface_config which is the method of class network and not subnetwork. That's why I have moved network_interface outside. I will think about how to make it better.

subnetwork = options.delete "subnetwork"
# Objectify the subnetwork if needed
unless subnetwork.is_a? Subnetwork
# Extract region_name from zone_name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can run rubocop -a filename to autocleanup these.

@icco
Copy link
Member

icco commented Apr 24, 2017

Oh also, can you make sure the network interface are up to date?

Copy link
Member

@Temikus Temikus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for this! 🎆

Please, see my comments.

@@ -36,12 +36,10 @@ def destroy(async = true)
operation
end

# Returns a ready API structure for insert_instance, used in insert_server request.
def get_as_interface_config(access_config = nil)
Copy link
Member

@Temikus Temikus Apr 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Providing some context. The following is my personal opinion, so please, correct me if I'm wrong here.

I implemented this method because I wanted the server insert request to properly work with network models #201, my reasoning for the method was:

  • Interface config and network resource do not match each-other well
  • insert_server request was getting overloaded, there were 30 additional lines to the main request method that very awkwardly constructed the network config.
  • what is better aware of what network looks like than the model itself?

Hence the placement in network model.
I want you to consider this before returning back to generating arrays in the insert code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the context. Finally I have left this method as it was (please see changes in the source code). By the way according to Google API documentation "if the network is not specified but the subnetwork is specified, the network is inferred". It means in the case when a user doesn't mention a network, it should not to be defaulted but to be inferred from a subnetwork. I find this a little bit strange.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Leila-Kuntar Thank you for this tidbit! I'll file some feedback internally.

unless subnetwork.is_a? Subnetwork
# Extract region_name from zone_name
l = zone_name.split(/-/)
region_name = l[0] + "-" + l[1]
Copy link
Member

@Temikus Temikus Apr 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid getting options by splitting parameters based on delimiters. Those can change and string manipulation is finicky.

For example, what if they change it? us-central1-f-private for example or us-legacy-central1-f...

I would suggest finding out the region programmatically, something like... get_zone(zone_name).body["region"]
, however, better dedup that with get_zone() in the request, since we're already getting it once, might as well reuse the called object and ingest it in the method.

Nit: I'd also suggest not to instantiate unneeded objects ('l'), unless they are reused so something like zone_name.split("-")[0..1].join("-") would probably be better in my opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your comments. I pass region_name as a parameter in handle_networks. Seems to be better now.

@@ -27,7 +27,6 @@ def insert_instance_group(group_name, zone, options = {})

unless options["subnetwork"].nil?
subnetwork_name = options["subnetwork"].split("/")[-1]
puts subnetwork_name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow, thanks for noticing this!

def get_as_interface_config(access_config = nil)
network_interface = { "network" => self_link }
network_interface["accessConfigs"] = [access_config] if access_config
network_interface
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra empty line detected at class body end.

@@ -35,7 +35,7 @@ def destroy(async = true)
operation.wait_for { ready? } unless async
operation
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.

@@ -233,14 +243,14 @@ def insert_server(server_name, zone_name, options = {}, *deprecated_args)
ohm.upcase == "MIGRATE" && "MIGRATE") || "TERMINATE"
end
body_object["scheduling"] = scheduling

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace detected.

Copy link
Member

@icco icco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small change, but other than that, lgtm. cc @Temikus

@@ -26,6 +26,7 @@ class Server < Fog::Compute::Server
# These attributes are not available in the representation of an 'instance' returned by the GCE API.
# They are useful only for the create process
attribute :network, :aliases => "network"
attribute :subnetwork, :aliases => "subnetwork"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need the alias here, neither does network.

@icco
Copy link
Member

icco commented May 7, 2017

Ping @Temikus

@Temikus
Copy link
Member

Temikus commented May 9, 2017

On it, should get to this by Monday.
Want to run some tests to make sure we don't break anything network-related.

EDIT: Changed timeline since I'm swamped.

@Temikus
Copy link
Member

Temikus commented May 15, 2017

@Wyosotis PTAL my review comment, workflow is broken for objects. Otherwise LGTM.

@Wyosotis
Copy link
Contributor Author

@Temikus It seems that I miss something. Which review comment do you mean?

Copy link
Member

@Temikus Temikus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Wyosotis PTAL

Looks like I didn't hit the "submit" button on requesting changes, apologies m(_ _)m
shaaame

end

# Return a networkInterfaces array
[network.get_as_interface_config(access_config)]
[network_interfaces]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're relying on a conditionally-existing variable. If one specifies network as an object and doesn't specify subnetwork, it equals to nil

server = connection.servers.create(
    :name => "fog-smoke-test-#{Time.now.to_i}",
    :disks => [disk],
    :machine_type => "n1-standard-1",
    :network => connection.networks.get('default'),
    :private_key_path => File.expand_path("~/.ssh/id_rsa"),
    :public_key_path => File.expand_path("~/.ssh/id_rsa.pub"),
    :zone_name => "us-central1-f",
    :username => ENV["USER"],
    :tags => ["fog"],
    :service_accounts => %w(sql-admin bigquery https://www.googleapis.com/auth/compute)
  )
/Users/temikus/Code/fog-devel/fog-google/lib/fog/google/shared.rb:188:in `build_excon_response': Invalid value for field 'resource': ''. At least one network interface is required. (Fog::Errors::Error)
	from /Users/temikus/Code/fog-devel/fog-google/lib/fog/google/shared.rb:159:in `request'
	from /Users/temikus/Code/fog-devel/fog-google/lib/fog/compute/google/requests/insert_server.rb:266:in `insert_server'
	from /Users/temikus/Code/fog-devel/fog-google/lib/fog/compute/google/models/server.rb:279:in `save'
	from /Users/temikus/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/fog-core-1.43.0/lib/fog/core/collection.rb:51:in `create'
	from create_instance.rb:21:in `test'
	from create_instance.rb:59:in `<main>'

This is actually caught by the new integration tests (not saying you should've been aware of them, though, since this is still in progress) - you can use this one to check the compatibility:

λ rake test TEST="test/**/test_compute_networks_collection.rb"                                                                                                  (1)
(in /Users/temikus/Code/fog-devel/fog-google)
Run options: --seed 19937

# Running:

E

Finished in 24.725542s, 0.0404 runs/s, 0.2022 assertions/s.

  1) Error:
TestComputeNetworksCollection#test_network_workflow:
Fog::Errors::Error: Invalid value for field 'resource': ''. At least one network interface is required.
    /Users/temikus/Code/fog-devel/fog-google/lib/fog/google/shared.rb:188:in `build_excon_response'
    /Users/temikus/Code/fog-devel/fog-google/lib/fog/google/shared.rb:159:in `request'
    /Users/temikus/Code/fog-devel/fog-google/lib/fog/compute/google/requests/insert_server.rb:265:in `insert_server'
    /Users/temikus/Code/fog-devel/fog-google/lib/fog/compute/google/models/server.rb:279:in `save'
    /Users/temikus/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/fog-core-1.43.0/lib/fog/core/collection.rb:51:in `create'
    /Users/temikus/Code/fog-devel/fog-google/test/integration/compute/test_compute_networks_collection.rb:39:in `test_network_workflow'

1 runs, 5 assertions, 0 failures, 1 errors, 0 skips
rake aborted!
Command failed with status (1): [ruby -I"lib:test" -I"/Users/temikus/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/rake-11.2.2/lib" "/Users/temikus/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/rake-11.2.2/lib/rake/rake_test_loader.rb" "test/integration/compute/test_compute_networks_collection.rb" ]

Tasks: TOP => test
(See full trace by running task with --trace)

Copy link
Contributor Author

@Wyosotis Wyosotis May 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Temikus or @icco could you tell me please where I should put google_project arguments? I have created the file ~/.fog with credentials as described in README.md but I get the following error

lkuntar@lkuntar-VirtualBox:~/workspace/forks/fog-google$ rake test TEST="test/**/test_compute_networks_collection.rb"
Run options: --seed 41630

# Running:

E

Finished in 0.004641s, 215.4935 runs/s, 0.0000 assertions/s.

  1) Error:
TestComputeNetworksCollection#test_network_workflow:
ArgumentError: Missing required arguments: google_project
    /var/lib/gems/2.2.0/gems/fog-core-1.43.0/lib/fog/core/service.rb:244:in `validate_options'
    /var/lib/gems/2.2.0/gems/fog-core-1.43.0/lib/fog/core/service.rb:268:in `handle_settings'
    /var/lib/gems/2.2.0/gems/fog-core-1.43.0/lib/fog/core/service.rb:98:in `new'
    /home/lkuntar/workspace/forks/fog-google/test/integration/compute/test_compute_networks_collection.rb:17:in `test_network_workflow'

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
/var/lib/gems/2.2.0/gems/fog-core-1.43.0/lib/fog/core/service.rb:244:in `validate_options': Missing required arguments: google_project (ArgumentError)
	from /var/lib/gems/2.2.0/gems/fog-core-1.43.0/lib/fog/core/service.rb:268:in `handle_settings'
	from /var/lib/gems/2.2.0/gems/fog-core-1.43.0/lib/fog/core/service.rb:98:in `new'
	from /home/lkuntar/workspace/forks/fog-google/test/integration/compute/test_compute_networks_collection.rb:11:in `block in <class:TestComputeNetworksCollection>'
	from /var/lib/gems/2.2.0/gems/minitest-5.10.1/lib/minitest.rb:58:in `call'
	from /var/lib/gems/2.2.0/gems/minitest-5.10.1/lib/minitest.rb:58:in `reverse_each'
	from /var/lib/gems/2.2.0/gems/minitest-5.10.1/lib/minitest.rb:58:in `block (2 levels) in autorun'
rake aborted!
Command failed with status (1)
/var/lib/gems/2.2.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => test

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@Temikus Temikus May 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Wyosotis Here's mine:

default:
  google_project: myproject
  google_json_key_location: /Users/temikus/.gcp/mykey.json
  public_key_path: ~/.ssh/id_rsa.pub
  private_key_path: ~/.ssh/id_rsa
test:
  google_project: myproject
  google_json_key_location: /Users/temikus/.gcp/mykey.json
  public_key_path: ~/.ssh/id_rsa.pub
  private_key_path: ~/.ssh/id_rsa

I think the testing suite picks up only "test" credentials, my bad, I'll add that to the example. Thanks for the note!

Copy link
Contributor Author

@Wyosotis Wyosotis May 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the replies.
Now this test passed well.

lkuntar@lkuntar-VirtualBox:~/workspace/forks/fog-google$ rake test TEST="test/**/test_compute_networks_collection.rb"
Run options: --seed 48938

# Running:

.

Finished in 25.083174s, 0.0399 runs/s, 0.3189 assertions/s.

1 runs, 8 assertions, 0 failures, 0 errors, 0 skips

@Temikus
Copy link
Member

Temikus commented May 30, 2017

@Wyosotis Thank you for your work!

LGTM

@Temikus Temikus merged commit f2d510c into fog:master May 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants