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

Google graph refresh #67

Merged
merged 9 commits into from
Sep 6, 2018
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module ManageIQ::Providers::Google
class CloudManager::Refresher < ManageIQ::Providers::BaseManager::Refresher
class CloudManager::Refresher < ManageIQ::Providers::BaseManager::ManagerRefresher
def parse_legacy_inventory(ems)
ManageIQ::Providers::Google::CloudManager::RefreshParser.ems_inv_to_hashes(ems, refresher_options)
end
Expand Down
11 changes: 11 additions & 0 deletions app/models/manageiq/providers/google/inventory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ManageIQ::Providers::Google::Inventory < ManageIQ::Providers::Inventory
require_nested :Collector
require_nested :Parser
require_nested :Persister

# Default manager for building collector/parser/persister classes
# when failed to get class name from refresh target automatically
def self.default_manager_name
"CloudManager"
end
end
12 changes: 12 additions & 0 deletions app/models/manageiq/providers/google/inventory/collector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class ManageIQ::Providers::Google::Inventory::Collector < ManageIQ::Providers::Inventory::Collector
require_nested :CloudManager
require_nested :NetworkManager

def initialize(_manager, _target)
super
end

def connection
@connection ||= manager.connect
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class ManageIQ::Providers::Google::Inventory::Collector::CloudManager < ManageIQ::Providers::Google::Inventory::Collector
attr_reader :project_key_pairs

def availability_zones
connection.zones.all
end

def flavors
flavors_by_zone = connection.list_aggregated_machine_types.items
flavors_by_zone.values.flat_map(&:machine_types).compact.uniq(&:id)
end

def flavor(flavor_uid, availability_zone_uid)
connection.get_machine_type(flavor_uid, availability_zone_uid)
end

def cloud_volumes
connection.disks.all
end

# !also parse vms! there
def cloud_volume_snapshots
connection.snapshots.all
end

def images
connection.images.all
end

def instances
connection.servers.all
end

# Used for ssh keys common to all instances in the project
def project_instance_metadata
if @common_instance_metadata.nil?
@common_instance_metadata = connection.projects.get(manager.project).common_instance_metadata
end
@common_instance_metadata
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
class ManageIQ::Providers::Google::Inventory::Collector::NetworkManager < ManageIQ::Providers::Google::Inventory::Collector
def cloud_networks
connection.networks.all
end

def cloud_subnets
if @subnetworks.nil?
@subnetworks = connection.subnetworks.all
# For a backwards compatibility, old GCE networks were created without subnet. It's not possible now, but
# GCE haven't migrated to new format. We will create a fake subnet for each network without subnets.
@subnetworks += connection.networks.select { |x| x.ipv4_range.present? }.map do |x|
Fog::Compute::Google::Subnetwork.new(
:name => x.name,
:gateway_address => x.gateway_ipv4,
:ip_cidr_range => x.ipv4_range,
:id => x.id,
:network => x.self_link,
:self_link => x.self_link,
:description => "Subnetwork placeholder for GCE legacy networks without subnetworks",
:creation_timestamp => x.creation_timestamp,
:kind => x.kind
)
end
end

@subnetworks
end

def network_ports
if @network_ports.nil?
@network_ports = []
connection.servers.all.collect do |instance|
@network_ports += instance.network_interfaces.each do |i|
i[:device_id] = instance.id
end
end
end

@network_ports
end

def floating_ips(status = :assigned)
if status == :assigned
# Fetch assigned floating IPs
network_ports.flat_map do |network_port|
network_port[:access_configs].to_a.collect do |access_config|
{:fixed_ip => network_port[:network_ip], :external_ip => access_config[:nat_ip]}
end
end
else
# Fetch non assigned static floating IPs
connection.addresses.reject { |x| x.status == "IN USE" }
end
end

# for IC firewall_rules
def firewalls
@firewalls ||= connection.firewalls.all
end

# for IC load_balancers
def forwarding_rules
connection.forwarding_rules.all
end

# for IC load_balancer_pools
def target_pools
# Right now we only support network-based load-balancers, instead of the
# more complicated HTTP/HTTPS load balancers.
# TODO(jsselman): Add support for http/https proxies
connection.target_pools.all
end

def get_health_check_from_link(link)
parts = parse_health_check_link(link)
unless parts
_log.warn("Unable to parse health check link: #{link}")
return nil
end

return nil unless connection.project == parts[:project]
get_health_check_cached(parts[:health_check])
end

# Lookup a VM in fog via its link to get the VM id (which is equivalent to
# the ems_ref).
#
# @param link [String] the full url to the vm
# @return [String, nil] the vm id, or nil if it could not be found
def get_vm_id_from_link(link)
parts = parse_vm_link(link)
unless parts
_log.warn("Unable to parse vm link: #{link}")
return nil
end

# Ensure our connection is using the same project; if it's not we can't
# do much
return nil unless connection.project == parts[:project]

get_vm_id_cached(parts[:zone], parts[:instance])
end

private

# Parses a VM's self_link attribute to extract the project name, zone, and
# instance name. Used when other services refer to a VM by its link.
#
# @param vm_link [String] the full url to the vm (e.g.
# "https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/foobar")
# @return [Hash{Symbol => String}, nil] a hash containing extracted components
# for `:project`, `:zone`, and `:instance`, or nil if the link did not
# match.
def parse_vm_link(vm_link)
link_regexp = %r{\Ahttps://www\.googleapis\.com/compute/v1/projects/([^/]+)/zones/([^/]+)/instances/([^/]+)\Z}
m = link_regexp.match(vm_link)
return nil if m.nil?

{
:project => m[1],
:zone => m[2],
:instance => m[3]
}
end

def parse_health_check_link(health_check_link)
link_regexp = %r{\Ahttps://www\.googleapis\.com/compute/v1/projects/([^/]+)/global/httpHealthChecks/([^/]+)\Z}

m = link_regexp.match(health_check_link)
return nil if m.nil?

{
:project => m[1],
:health_check => m[2]
}
end

# Look up a VM in fog via a given zone and instance for the current
# project to get the VM id. Note this method caches matched values during
# this instance's entire lifetime.
#
# @param zone [String] the zone of the vm
# @param instance [String] the name of the vm
# @return [String, nil] the vm id, or nil if it could not be found
def get_vm_id_cached(zone, instance)
@vm_cache ||= {}

return @vm_cache.fetch_path(zone, instance) if @vm_cache.has_key_path?(zone, instance)

begin
@vm_cache.store_path(zone, instance, connection.get_server(instance, zone).id)
rescue Fog::Errors::Error, ::Google::Apis::ClientError => err
m = "Error during data collection for [#{manager&.name}] id: [#{manager&.id}] when querying link for vm_id: #{err}"
_log.warn(m)
_log.warn(err.backtrace.join("\n"))
nil
end
end

def get_health_check_cached(health_check)
@health_check_cache ||= {}

return @health_check_cache.fetch_path(health_check) if @health_check_cache.has_key_path?(health_check)

@health_check_cache.store_path(health_check, connection.http_health_checks.get(health_check))
rescue Fog::Errors::Error => err
m = "Error during data collection for [#{manager&.name}] id: [#{manager&.id}] when querying link for health check: #{err}"
_log.warn(m)
_log.warn(err.backtrace.join("\n"))
nil
end
end
6 changes: 6 additions & 0 deletions app/models/manageiq/providers/google/inventory/parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ManageIQ::Providers::Google::Inventory::Parser < ManageIQ::Providers::Inventory::Parser
require_nested :CloudManager
require_nested :NetworkManager

VENDOR_GOOGLE = "google".freeze
end
Loading