154 lines
6.1 KiB
Ruby
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
|