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

VMware provider IP discovery fix #221

Merged
merged 2 commits into from
Mar 29, 2018

Conversation

slemrmartin
Copy link
Contributor

Recognition of vSphere product based on API info instead ports scanning
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1559347

Steps to reproduce:
Have a VMWare Virtual Center (vSphere) on known IP

  1. Navigate to Compute -> Infrastructure -> Providers
  2. Configuration -> Discover Infrastructure Providers
  3. Input valid IP range and choose valid provider, click Start

Cc @agrare, @Ladas
@miq-bot add_label bug

Recognition of vSphere product based on API info instead ports scanning

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1559347
@miq-bot miq-bot added the bug label Mar 26, 2018
@agrare agrare self-assigned this Mar 26, 2018
end
rescue StandardError => err
Copy link
Contributor

Choose a reason for hiding this comment

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

rescue StandardError => err is the same as rescue => err

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it was as you write before rubocop -a

Copy link
Contributor

@Ladas Ladas left a comment

Choose a reason for hiding this comment

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

Looks good code wise, @agrare will need to review correctness, since that is outside of my area of expertise. :-)

# a network than VC servers.
# Obtains info about IP address from vSphere Web Service API
# @param ost [OpenStruct]
def self.access_webservice(ost)
Copy link
Member

Choose a reason for hiding this comment

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

Since you're only using ost.ipaddr can you just pass in the ipaddress? The whole openstruct is leaking too much info from the caller to here

_log&.debug("Vmware::Discovery: ip = #{ost.ipaddr}, Machine is an VMWare Server product.")
:vmwareserver
else
_log&.error("Vmware::Discovery: ip: #{ost.ipaddr}, Unknown product: #{info&.productLineId}")
Copy link
Member

Choose a reason for hiding this comment

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

Should be ip = ... to stay consistent with the rest of these

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why consistency of sentence in log (between different log levels) has bigger priority than given information? Isn't it valuable to know, which unexpected value is inside?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ahhh, sorry, you mean = instead of : ...I noticed after I submitted comment above :)

Copy link
Member

Choose a reason for hiding this comment

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

Oh yeah sorry I meant the : part, not the rest of the info :)


# Check if we have ESX ports open
if !found_vc && ost.discover_types.include?(:esx) && ManageIQ::NetworkDiscovery::Port.any_open?(ost, ESX_PORTS)
ost.hypervisor << hypervisor if hypervisor
Copy link
Member

Choose a reason for hiding this comment

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

Don't you still need to check if the hypervisor type is in the ost.discover_types?

return
# Get Info from VMware (vSphere) Web Service API
access_webservice(ost) do |info|
if add_hypervisor(ost, info)
Copy link
Member

Choose a reason for hiding this comment

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

I feel like add_hypervisor and add_os are doing too much.
I would rather see something like:

hvisor_type = hypervisor_type(info)
if ost.discover_types.include?(hvisor_type)
  ost.hypervisor << hvisor_type
  ost.os << hvisor_os_type(info)
end

# Check if we have VC ports
if ost.discover_types.include?(:virtualcenter)
checked_vc = true
yield info
Copy link
Member

Choose a reason for hiding this comment

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

I don't think yielding the info is needed when there's no cleanup here. How about just info = retrieve_about_info(ost.ipaddr) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

please explain, why is this better - do you mean that code is more readable without yield?


checked_vc = false
found_vc = false
_log&.debug("Vmware::Discovery: ip = #{ost.ipaddr}, Connected to VMware webservice.")
Copy link
Member

Choose a reason for hiding this comment

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

I don't think _log&. is needed since as long as you include VMDB::Logging _log will always be defined

@slemrmartin
Copy link
Contributor Author

Thanks for review!
Additionally I made related PR: ManageIQ/manageiq#17229 with small fix
Doesn't block this

# Check if VMware Server
ost.hypervisor << :vmwareserver if ManageIQ::NetworkDiscovery::Port.scan_open(ost, SERVER_CONSOLE_PORTS).length == 2
# Get Info from VMware (vSphere) Web Service API
info = retrieve_webservice_info(ost.ipaddr)

Copy link
Member

Choose a reason for hiding this comment

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

How about return if info.nil? here and not need to do info&.productLineId and info&.osType below?

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 saw codeclimate only few times, but doesn't it evaluate as higher cognitive complexity when using return in middle of method?

Copy link
Member

Choose a reason for hiding this comment

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

If the code makes more sense I wouldn't worry about what codeclimate says. If you'd rather one return you can raise in retrieve_webservice_info if vim.about is nil

$log&.debug("Vmware::Discovery: ip = #{ost.ipaddr}, Connected to VMware webservice. Machine is either ESX or VirtualCenter.")
if ost.discover_types&.include?(hvisor_type)
ost.hypervisor << hvisor_type
ost.os << hypervisor_os_type(info&.osType)
Copy link
Member

Choose a reason for hiding this comment

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

Probably would be good to add unless info.osType.nil? here so we don't potentially have ost.os = [nil] and cause the caller issues

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ost.os should result to be :mswin or :linux only

I think it is better option than result ost.hypervisor.size != ost.os.size

Copy link
Member

Choose a reason for hiding this comment

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

That's fair, osType is a required field in AboutInfo so it shouldn't be nil

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 still don't see where is the problem - how should be possible to have ost.os = [nil] with this code?

If osType will be nil, then hypervisor_os_type returns :linux

Copy link
Member

Choose a reason for hiding this comment

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

Ah was getting ahead of myself, I was thinking hypervisor_os_type should check if osType is nil instead of just defaulting to :linux but then ost.os would be [nil] so thought better to check if nil before calling it so ost.os = [nil] was an intermediate step in my head that I didn't write down haha

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, now I'm confused what is your recommendation :))
If I check if osType isn't nil instead of defaulting to :linux, then ost.hypervisor and ost.os arrays can have different sizes. It doesn't cause error, but I don't know if next code is ok with that

Copy link
Member

Choose a reason for hiding this comment

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

It looks like it just won't save the operating_system automatically https://github.com/ManageIQ/manageiq/blob/master/app/models/host.rb#L994
If you want to just have it default to linux that's fine


# Next check for ESX or VC. Since VC shares some port numbers with ESX, we check VC before ESX
rescue => err
_log.warn("Vmware::Discovery: ip = #{ost.ipaddr}, Failed to connect to VMware webservice: #{err}.")
Copy link
Member

Choose a reason for hiding this comment

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

Since this will be the case for every IP that isn't a VCenter on the subnet being scanned this should still be debug

def self.retrieve_webservice_info(ip)
require 'VMwareWebService/MiqVimClientBase'
vim = MiqVimClientBase.new(ip, "test", "test")
info = vim&.sic&.about
Copy link
Member

Choose a reason for hiding this comment

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

I just checked again and :about is an attr_reader on VimService so you can skip the .sic in the middle

@agrare
Copy link
Member

agrare commented Mar 29, 2018

@slemrmartin looking really good, just a couple of small things

@miq-bot
Copy link
Member

miq-bot commented Mar 29, 2018

Checked commits slemrmartin/manageiq-providers-vmware@abe3151~...88277fc with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
1 file checked, 1 offense detected

app/models/manageiq/providers/vmware/discovery.rb

Copy link
Member

@agrare agrare left a comment

Choose a reason for hiding this comment

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

👍 will merge when green

@agrare agrare merged commit 88277fc into ManageIQ:master Mar 29, 2018
agrare added a commit that referenced this pull request Mar 29, 2018
@agrare agrare added this to the Sprint 83 Ending Apr 9, 2018 milestone Mar 29, 2018
@slemrmartin slemrmartin deleted the infra-provider-discovery branch March 29, 2018 14:04
@simaishi
Copy link
Contributor

@slemrmartin Can this be gaprindashvili/yes ?

@slemrmartin
Copy link
Contributor Author

Not sure - @agrare ?

@agrare
Copy link
Member

agrare commented Apr 12, 2018

@simaishi yes it can, #181 was backported so it should be a clean cherry-pick. Any further back and @slemrmartin will need to create a backport PR.

@simaishi
Copy link
Contributor

Gaprindashvili backport details:

$ git log -1
commit b3fe8b34b664cbf06e78c5c2d2cb7feb818a47ed
Author: Adam Grare <agrare@redhat.com>
Date:   Thu Mar 29 10:01:54 2018 -0400

    Merge pull request #221 from slemrmartin/infra-provider-discovery
    
    VMware provider IP discovery fix
    (cherry picked from commit 56b62a704e62c3e9aa7b64968cd6b75c984ea26f)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1566557

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants