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

Advanced networking placement features and automate exposure #13608

Merged
merged 8 commits into from
Feb 9, 2017
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ def do_clone_task_check(clone_task_ref)
instance = openstack.handled_list(:servers).detect { |s| s.id == clone_task_ref }
status = instance.state.downcase.to_sym

if status == :error
raise MiqException::MiqProvisionError, "An error occurred while provisioning Instance #{instance.name}"
end
return true if status == :active
return false, status
end
Expand Down
42 changes: 42 additions & 0 deletions app/models/manageiq/providers/openstack/cloud_manager/vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,48 @@ def floating_ip
floating_ips.first
end

def associate_floating_ip_from_network(public_network, port = nil)
ext_management_system.with_provider_connection(:service => "Network",
:tenant_name => cloud_tenant.name) do |connection|
unless port
network_ports.each do |network_port|
# Cycle through all ports and find one that is actually connected to the public network with router,
if network_port.public_networks.detect { |x| x.try(:ems_ref) == public_network.ems_ref }
port = network_port
break
end
end
end
unless port
raise(MiqException::MiqNetworkPortNotDefinedError,
"Neutron port for floating IP association is not defined for OpenStack"\
"network #{public_network.ems_ref} and EMS '#{ext_management_system.name}'")
end

connection.create_floating_ip(public_network.ems_ref, :port_id => port.ems_ref)
end
end

def delete_floating_ips(floating_ips)
# TODO(lsmola) we have the method here because we need to take actual cloud_tenant from the VM.
# This should be refactored to FloatingIP, when we can take tenant from elsewhere, Like user
# session? They have it in session in Horizon, ehich correlates the teannt in keytsone token.
ext_management_system.with_provider_connection(:service => "Network",
:tenant_name => cloud_tenant.name) do |connection|
floating_ips.each do |floating_ip|
begin
connection.delete_floating_ip(floating_ip.ems_ref)
rescue StandardError => e
# The FloatingIp could have been deleted by another process
_log.info("Could not delete floating IP #{floating_ip} in EMS "\
"'#{ext_management_system.name}'. Error: #{e}")
end
# Destroy it also in db, so we don't have to wait for refresh.
floating_ip.destroy
end
end
end

def provider_object(connection = nil)
connection ||= ext_management_system.connect
connection.servers.get(ems_ref)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,77 @@ def self.connection_options(cloud_tenant = nil)
connection_options
end

def ip_address_total_count
# TODO(lsmola) Rather storing this in DB? It should be changing only in refresh
@ip_address_total_count ||= cloud_subnets.all.sum do |subnet|
# We substract 1 because the first address of the pool is always reserved. For private network it is for DHCP, for
# public network it's a port for Router.
subnet.allocation_pools.sum { |x| (IPAddr.new(x["start"])..IPAddr.new(x["end"])).map(&:to_s).count - 1 }
end
end

def ip_address_left_count(reload = false)
@ip_address_left_count = nil if reload
@ip_address_left_count ||= ip_address_total_count - ip_address_used_count(reload)
end

def ip_address_left_count_live(reload = false)
@ip_address_left_count_live = nil if reload
# Live method is asking API drectly for current count of consumed addresses
@ip_address_left_count_live ||= ip_address_total_count - ip_address_used_count_live(reload)
end

def ip_address_used_count(reload = false)
@ip_address_used_count = nil if reload
if @public
# Number of all floating Ips, since we are doing association by creating FloatingIP, because
# associate is not atomic.
@ip_address_used_count ||= floating_ips.count
else
@ip_address_used_count ||= vms.count
end
end

def ip_address_used_count_live(reload = false)
@ip_address_used_count_live = nil if reload
if @public
# Number of ports with fixed IPs plugged into the network. Live means it talks directly to OpenStack API
# TODO(lsmola) we probably need paginated API call, there should be no multitenancy needed, but the current
# UI code allows to mix tenants, so it could be needed, athough netron doesn seem to have --all-tenants calls,
# so when I use admin, I can see other tenant resources. Investigate, fix.
@ip_address_used_count_live ||= ext_management_system.with_provider_connection(
:service => "Network",
:tenant_name => cloud_tenant.name
) do |connection|
connection.floating_ips.all(:floating_network_id => ems_ref).count
end
else
@ip_address_used_count_live ||= ext_management_system.with_provider_connection(
:service => "Network",
:tenant_name => cloud_tenant.name
) do |connection|
connection.ports.all(:network_id => ems_ref, :device_owner => "compute:None").count
end
end
end

def ip_address_utilization(reload = false)
@ip_address_utilization = nil if reload
# If total count is 0, utilization should be 100
@ip_address_utilization ||= begin
ip_address_total_count > 0 ? (100.0 / ip_address_total_count) * ip_address_used_count(reload) : 100
end
end

def ip_address_utilization_live(reload = false)
@ip_address_utilization_live = nil if reload
# Live method is asking API drectly for current count of consumed addresses
# If total count is 0, utilization should be 100
@ip_address_utilization_live ||= begin
ip_address_total_count > 0 ? (100.0 / ip_address_total_count) * ip_address_used_count_live(reload) : 100
end
end

private

def connection_options(cloud_tenant = nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class MiqAeServiceManageIQ_Providers_Openstack_CloudManager_Vm < MiqAeServiceVmC
expose :associate_floating_ip, :override_return => nil
expose :disassociate_floating_ip, :override_return => nil

expose :associate_floating_ip_from_network
expose :delete_floating_ips

def attach_volume(volume_id, device = nil, options = {})
sync_or_async_ems_operation(options[:sync], "attach_volume", [volume_id, device])
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
module MiqAeMethodService
class MiqAeServiceManageIQ_Providers_Openstack_NetworkManager_CloudNetwork < MiqAeServiceCloudNetwork
expose :ip_address_left_count
expose :ip_address_left_count_live
expose :ip_address_total_count
expose :ip_address_used_count
expose :ip_address_used_count_live
expose :ip_address_utilization
expose :ip_address_utilization_live
end
end
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module MiqAeMethodService
class MiqAeServiceManageIQ_Providers_Openstack_NetworkManager_FloatingIp < MiqAeServiceFloatingIp
expose :destroy
end
end
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module MiqAeMethodService
class MiqAeServiceNetworkPort < MiqAeServiceModelBase
expose :ext_management_system, :association => true
expose :cloud_tenant, :association => true
expose :cloud_subnets, :association => true
expose :device, :association => true
expose :ext_management_system, :association => true
expose :public_network, :association => true
expose :public_networks, :association => true
end
end
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
module MiqAeMethodService
class MiqAeServiceVmCloud < MiqAeServiceVm
expose :availability_zone, :association => true
expose :flavor, :association => true
expose :cloud_network, :association => true
expose :cloud_networks, :association => true
expose :cloud_subnet, :association => true
expose :cloud_subnets, :association => true
expose :network_ports, :association => true
expose :network_routers, :association => true
expose :flavor, :association => true
expose :floating_ip, :association => true
expose :floating_ips, :association => true
expose :security_groups, :association => true
expose :key_pairs, :association => true
expose :network_ports, :association => true
expose :network_routers, :association => true
expose :private_networks, :association => true
expose :public_networks, :association => true
expose :security_groups, :association => true
end
end