-
Notifications
You must be signed in to change notification settings - Fork 145
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
Add templates and instance group managers #348
Conversation
module Compute | ||
class Google | ||
class Mock | ||
def set_instance_template(instance_group_manager, instance_template) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/UnusedMethodArgument: Unused method argument - instance_group_manager. If it's necessary, use _ or _instance_group_manager as an argument name to indicate that it won't be used. You can also write as set_instance_template() if you want the method to accept any arguments but don't care about them.
Lint/UnusedMethodArgument: Unused method argument - instance_template. If it's necessary, use _ or _instance_template as an argument name to indicate that it won't be used. You can also write as set_instance_template() if you want the method to accept any arguments but don't care about them.
class Real | ||
def recreate_instances(instance_group_manager, instances) | ||
request = ::Google::Apis::ComputeV1::InstanceGroupManagersAbandonInstancesRequest.new( | ||
:instances => instances.map{|x| x.self_link} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/SpaceBeforeBlockBraces: Space missing to the left of {.
Layout/SpaceInsideBlockBraces: Space between { and | missing.
Style/SymbolProc: Pass &:self_link as an argument to map instead of a block.
Layout/SpaceInsideBlockBraces: Space missing inside }.
module Compute | ||
class Google | ||
class Mock | ||
def recreate_instances(instance_group_manager, instances) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/UnusedMethodArgument: Unused method argument - instance_group_manager. If it's necessary, use _ or _instance_group_manager as an argument name to indicate that it won't be used. You can also write as recreate_instances() if you want the method to accept any arguments but don't care about them.
Lint/UnusedMethodArgument: Unused method argument - instances. If it's necessary, use _ or _instances as an argument name to indicate that it won't be used. You can also write as recreate_instances() if you want the method to accept any arguments but don't care about them.
class Google | ||
|
||
class Mock | ||
def list_instance_templates() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/DefWithParentheses: Omit the parentheses in defs when the method doesn't accept any arguments.
module Fog | ||
module Compute | ||
class Google | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body beginning.
end | ||
operation | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body end.
|
||
load(data.map(&:to_h)) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body end.
def abandon_instances instances | ||
service.abandon_instances self, instances | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body end.
service.recreate_instances self, instances | ||
end | ||
|
||
def abandon_instances instances |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/MethodDefParentheses: Use def with parentheses when there are parameters.
service.set_instance_template self, instance_template | ||
end | ||
|
||
def recreate_instances instances |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/MethodDefParentheses: Use def with parentheses when there are parameters.
attribute :instance_group, :aliases => "instanceGroup" | ||
attribute :instance_template, :aliases => "instanceTemplate" | ||
|
||
def set_instance_template instance_template |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/MethodDefParentheses: Use def with parentheses when there are parameters.
20974d8
to
6e23342
Compare
|
||
def all(filters = {}) | ||
if filters[:zone] | ||
data = Array(service.list_aggregated_instance_group_managers(filters[:zone])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to cast this as an Array
? What does it return normally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
class InstanceGroupManagers < Fog::Collection | ||
model Fog::Compute::Google::InstanceGroupManager | ||
|
||
def all(filters = {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data = []
should be the first line in this function to properly declare scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
data = Array(service.list_aggregated_instance_group_managers(filters[:zone])) | ||
else | ||
data = [] | ||
service.list_aggregated_instance_group_managers.items.each_value do |group| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this could be simplified to
data = service.list_aggregated_instance_group_managers.items.map {|group| group.instance_group_managers }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not written like that in others files, but yes, we can do that.
Also, feel free to ignore those codeclimate errors. |
|
||
class Real | ||
def list_instance_group_managers(zone) | ||
@compute.list_instance_group_managers(@project, zone) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/IndentationWidth: Use 2 (not 3) spaces for indentation.
First of all - thank you! Let me write in a quick test for this and I’ll check if this fits our standard model/collection lifecycle. I aim to respond by Wednesday (SYD) at the latest. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good from a code perspective. Just need @Temikus and we're good to go.
Ok, added a simple lifecycle test:
Results:
We're missing a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall - good work, thank you!
However, needs some adjustments, esp. to the :properties parameter as it's unclear how they should look like and the :properties do not accept hashes.
module Compute | ||
class Google | ||
class InstanceGroupManagers < Fog::Collection | ||
model Fog::Compute::Google::InstanceGroupManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing a get
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
module Fog | ||
module Compute | ||
class Google | ||
class InstanceGroupManager < Fog::Model |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing a save
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Also added a bunch of attributes; reload and destroy.
instance_template = ::Google::Apis::ComputeV1::InstanceTemplate.new( | ||
:description => description, | ||
:name => name, | ||
:properties => properties, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm reading this correctly, properties
will need to be an instance of google api client's InstanceProperties
class.
If so - fog avoids exposing underlying API structures, so parameters need to be provided in hashes, see: https://github.com/fog/fog-google/blob/985cd021bcfe4f403deb7c0077997529d529b4b1/lib/fog/compute/google/requests/insert_server.rb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A hash seeme to be enough. Added some doc.
end | ||
|
||
class Real | ||
def insert_instance_template(name, properties, description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's not entirely clear what properties
should contain and in what structure, can you please add a doc comment?
E.g.:
fog-google/lib/fog/compute/google/requests/insert_server.rb
Lines 38 to 60 in 985cd02
# Create a new instance (virtual machine). | |
# | |
# This method allows you to use low-level request options and thus | |
# expects instance options similar to API requests. If you don't need to | |
# modify low-level request options, consider using the | |
# Fog::Compute::Google::Servers collection object instead. | |
# | |
# @example minimal server creation | |
# my_operation = client.insert_server( | |
# "my-server", | |
# "us-central1-a", | |
# :machine_type => "f1-micro", | |
# :disks => [ | |
# { | |
# :initialize_params => { | |
# :source_image => "projects/debian-cloud/global/images/family/debian-8" | |
# } | |
# } | |
# ] | |
# ) | |
# | |
# @param instance_name [String] | |
# Name to assign to the created server. Must be unique within the specified zone. |
if instance_template = service.get_instance_template(identity) | ||
new(instance_template.to_h) | ||
end | ||
rescue Fog::Errors::NotFound |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should rescue Google::Apis::ClientError: notFound
, this currently doesn't return nil as it should.
For an example see:
fog-google/lib/fog/compute/google/models/servers.rb
Lines 29 to 42 in 985cd02
def get(identity, zone = nil) | |
response = nil | |
if zone | |
response = service.get_server(identity, zone).to_h | |
else | |
server = all(:filter => "name eq .*#{identity}").first | |
response = server.attributes if server | |
end | |
return nil if response.nil? | |
new(response) | |
rescue ::Google::Apis::ClientError => e | |
raise e unless e.status_code == 404 | |
nil | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
7848ae9
to
65bc4b3
Compare
end | ||
|
||
class Real | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body beginning.
|
||
class Real | ||
def insert_instance_group_manager(name, zone, instance_template, base_instance_name, | ||
target_size, target_pools, named_ports, description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/AlignParameters: Align the parameters of a method definition if they span more than one line.
class Google | ||
class Mock | ||
def insert_instance_group_manager(_name, _zone, _instance_template, _base_instance_name, | ||
_target_size, _target_pools, _named_ports, _description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/AlignParameters: Align the parameters of a method definition if they span more than one line.
requires :name, :zone, :base_instance_name, :target_size, :instance_template | ||
|
||
data = service.insert_instance_group_manager(name, zone.split("/")[-1], instance_template, base_instance_name, | ||
target_size, target_pools, named_ports, description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/AlignParameters: Align the parameters of a method call if they span more than one line.
end | ||
|
||
class Real | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body beginning.
|
||
class Real | ||
def insert_instance_group_manager(name, zone, instance_template, base_instance_name, | ||
target_size, target_pools, named_ports, description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/AlignParameters: Align the parameters of a method definition if they span more than one line.
class Google | ||
class Mock | ||
def insert_instance_group_manager(_name, _zone, _instance_template, _base_instance_name, | ||
_target_size, _target_pools, _named_ports, _description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/AlignParameters: Align the parameters of a method definition if they span more than one line.
requires :name, :zone, :base_instance_name, :target_size, :instance_template | ||
|
||
data = service.insert_instance_group_manager(name, zone.split("/")[-1], instance_template, base_instance_name, | ||
target_size, target_pools, named_ports, description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/AlignParameters: Align the parameters of a method call if they span more than one line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found some other issues that prevent proper model lifecycle, PTAL
Apologies for yet another iteration m(_ _)m
load(data.map(&:to_h)) | ||
end | ||
|
||
def get(identity, zone) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get
should have at most one required argument.
See servers
for an example:
fog-google/lib/fog/compute/google/models/servers.rb
Lines 30 to 40 in a142a85
def get(identity, zone = nil) | |
response = nil | |
if zone | |
response = service.get_server(identity, zone).to_h | |
else | |
server = all(:filter => "name eq .*#{identity}").first | |
response = server.attributes if server | |
end | |
return nil if response.nil? | |
new(response) | |
rescue ::Google::Apis::ClientError => e |
I do realise disks
have a zone
requirement but that's not by design and will be fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
def all | ||
data = service.list_instance_templates.items | ||
load(data.map(&:to_h)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use safe navigation or define as empty array, this will fail if there are no instance templates created.
I.e.: NoMethodError: undefined method
map' for nil:NilClass`
This should work:
data = service.list_instance_templates.items || []
|
||
def destroy(async = true) | ||
requires :name | ||
operation = service.delete_instance_template(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to return a Fog::Compute::Google::Operation model here, see your save
method.
Otherwise you'll get a Google API client class that doesn't respond to .wait_for
:
NoMethodError: undefined method `wait_for' for #<Google::Apis::ComputeV1::Operation:0x00007fd00aed3f00>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
instance_group_manager = ::Google::Apis::ComputeV1::InstanceGroupManager.new( | ||
:description => description, | ||
:name => name, | ||
:instance_template => instance_template.self_link, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This assumes that an object is going to be passed in.
Usually models should accept self_links and resource names as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in the three requests.
attribute :self_link, :aliases => "selfLink" | ||
attribute :description | ||
# Properties is a hash describing the templates | ||
# @see https://cloud.google.com/compute/docs/reference/rest/v1/instanceTemplates/insert |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: If at all possible, add a minimal hash example. The doc itself is quite complicated and it took me a while to figure the right parameters out (didn't work with IGM api before). For newer people that haven't worked with Google API's at all that may be a higher barrier.
I came up with this as a minimal test case:
:properties => {
:machine_type => TEST_MACHINE_TYPE,
:disks => [{
:boot => true,
:initialize_params =>
{:source_image => "projects/ubuntu-os-cloud/global/images/ubuntu-1804-bionic-v20180522"}
}],
:network_interfaces => [{ :network => "global/networks/default" }]
}
, but wanted to check with you since you can probably provide a better real-life example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
No, I'm using template to clone existing template and change the image.
order_by: nil, page_token: nil) | ||
@compute.list_instance_group_managers( | ||
@project, zone, :filter => filter, :max_results => max_results, | ||
:order_by => order_by, :page_token => page_token) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/AlignHash: Align the elements of a hash literal if they span more than one line.
Layout/MultilineMethodCallBraceLayout: Closing method call brace must be on the line after the last argument when opening brace is on a separate line from the first argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests pass \o/
I'm happy how this turned out. Thank you very much for your contribution and patience!
Sorry, did not write tests, but I'm using it in prod.