fuel-plugin-nsx-t/deployment_scripts/puppet/modules/nsxt/lib/puppet/provider/nsxt_create_transport_node/nsxt_create_transport_node.rb

154 lines
6.1 KiB
Ruby

require 'socket'
require File.join(File.dirname(__FILE__),'..', 'nsxtutils')
Puppet::Type.type(:nsxt_create_transport_node).provide(:nsxt_create_transport_node, :parent => Puppet::Provider::Nsxtutils) do
# need this for work nsxtcli method, otherwise not work
commands :nsxcli => 'nsxcli'
def create
host_switch_profile_ids = [{'key' => 'UplinkHostSwitchProfile', 'value' => @resource[:uplink_profile_id] }]
pnics = create_pnics_array(@resource[:pnics])
node_id = get_node_id
display_name = Socket.gethostname
# the host switch name of the transport zone must match the host switch name to create transport nodes
host_switch_name = get_host_switch_name(@resource[:managers], @resource[:transport_zone_id])
request = {'display_name' => display_name,
'node_id' => node_id,
'host_switches' => [{'host_switch_name' => host_switch_name,
'static_ip_pool_id' => @resource[:static_ip_pool_id],
'host_switch_profile_ids' => host_switch_profile_ids,
'pnics' => pnics}],
'transport_zone_endpoints' => [{'transport_zone_id' => @resource[:transport_zone_id]}]
}
# puppet retrun string if provide array parametr with single element
# https://projects.puppetlabs.com/issues/9850
transport_zone_profile_ids = @resource[:transport_zone_profile_ids]
if not transport_zone_profile_ids.instance_of? Array
transport_zone_profile_ids = [transport_zone_profile_ids]
end
if not transport_zone_profile_ids[0].to_s.empty?
request['transport_zone_endpoints'].push(transport_zone_profile_ids)
end
debug("Attempting to create a transport node")
@resource[:managers].each do |manager|
api_url = "https://#{manager}/api/v1/transport-nodes"
begin
response = post_nsxt_api(api_url, @resource[:username], @resource[:password], request.to_json, @resource[:ca_file])
rescue => error
raise Puppet::Error,("\nFailed to create the transport node: #{error.message}\n")
end
if not response.to_s.empty?
# 12 retry x 15 sleep time = 3 minutes timeout
retry_count = 12
while retry_count > 0
if exists?
notice("Node '#{node_id}' added to NSX-T as transport node")
return true
else
retry_count -= 1
sleep 15
end
end
end
end
raise Puppet::Error,("\nFailed to create the transport node, status in NSX-T manager not updated\n")
end
def exists?
connected_managers = nsxtcli("get controllers")
if connected_managers.include? "connected"
node_id = get_node_id
if not node_id.empty?
@resource[:managers].each do |manager|
if check_node_lcp_connected(manager, node_id)
debug("Node '#{node_id}' connected to controllers and LCP connectivity status UP on '#{manager}'")
return true
end
end
else
raise Puppet::Error,("\nFailed to create the transport node:\nNode not registered in management plane\n")
end
end
debug("Node NOT connected to NSX-T controllers")
return false
end
def destroy
debug("Attempting to delete a transport node")
node_id = get_node_id
@resource[:managers].each do |manager|
transport_node_id = get_transport_node_id(manager, node_id, @resource[:ca_file])
if not transport_node_id.empty?
api_url = "https://#{manager}/api/v1/transport-nodes/#{transport_node_id}"
begin
response = delete_nsxt_api(api_url, @resource[:username], @resource[:password], @resource[:ca_file])
rescue => error
raise Puppet::Error,("\nFailed to delete the transport node: #{error.message}\n")
end
if response
# 12 retry x 15 sleep time = 3 minutes timeout
retry_count = 12
while retry_count > 0
if not exists?
notice("Transport node '#{node_id}' delete from NSX-T")
return true
else
retry_count -= 1
sleep 15
end
end
end
end
end
raise Puppet::Error,("\nFailed to delete the transport node.\n")
end
def check_node_lcp_connected(manager, node_id)
api_url = "https://#{manager}/api/v1/fabric/nodes/#{node_id}/status"
response = get_nsxt_api(api_url, @resource[:username], @resource[:password], @resource[:ca_file])
if not response.to_s.empty?
if response['lcp_connectivity_status'] == 'UP'
debug("Node '#{node_id}' LCP status UP on '#{manager}'")
return true
else
debug("Node LCP status '#{response['lcp_connectivity_status']}' on '#{manager}'")
if not response['lcp_connectivity_status_details'].empty?
response['lcp_connectivity_status_details'].each do |details|
debug("On #{details['control_node_ip']} status: #{details['status']} failure_status: #{details['failure_status']}")
end
end
end
else
debug("Node LCP status NOT UP on '#{manager}'")
end
return false
end
def get_host_switch_name(managers, transport_zone_id)
managers.each do |manager|
debug("Attempt to get host_switch_name for '#{transport_zone_id}' transport zone from '#{manager}' manager")
api_url = "https://#{manager}/api/v1/transport-zones/#{transport_zone_id}"
response = get_nsxt_api(api_url, @resource[:username], @resource[:password], @resource[:ca_file])
if not response.to_s.empty?
return response['host_switch_name']
end
end
raise Puppet::Error,("\nCannot get host_switch_name for '#{transport_zone_id}' transport zone.\n")
end
def create_pnics_array(pnics)
result_pnic_pairs = []
# https://projects.puppetlabs.com/issues/9850
if not pnics.instance_of? Array
pnics = [pnics]
end
pnics.each do |pnic_pair|
device,uplink = pnic_pair.split(':')
result_pnic_pairs.push({'device_name' => device.strip, 'uplink_name' => uplink.strip})
end
return result_pnic_pairs
end
end