sub get_firewall_ruleset_info()

in managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm [3686:3806]


sub get_firewall_ruleset_info {
	my $self = shift;
	if (ref($self) !~ /VCL::Module/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}
	
	return $ENV->{firewall_ruleset_info} if defined($ENV->{firewall_ruleset_info});
	
	my $vmhost_computer_name = $self->data->get_vmhost_hostname();
	
	my $ruleset_info = {};
	
	# Get the enabled/disabled status of each ruleset
	my $ruleset_list_command = "esxcli --formatter=csv network firewall ruleset list";
	my ($ruleset_list_exit_status, $ruleset_list_output) = $self->vmhost_os->execute($ruleset_list_command);
	if (!defined($ruleset_list_output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute command on VM host $vmhost_computer_name: $ruleset_list_command");
		return;
	}
	elsif ($ruleset_list_exit_status ne 0) {
		notify($ERRORS{'WARNING'}, 0, "failed to retrieve firewall ruleset info from VM host $vmhost_computer_name, exit status: $ruleset_list_exit_status, command:\n$ruleset_list_command\noutput:\n" . join("\n", @$ruleset_list_output));
		return 0;
	}
	
	# Enabled,Name,
	# true,sshServer,
	# true,sshClient,
	# true,nfsClient,
	# false,nfs41Client,
	# ...
	for my $line (@$ruleset_list_output) {
		if ($line !~ /(true|false)/) {
			next;
		}
		my ($enabled, $ruleset_name) = split(/,/, $line);
		if ($enabled =~ /true/i) {
			$ruleset_info->{$ruleset_name}{enabled} = 1;
		}
		else {
			$ruleset_info->{$ruleset_name}{enabled} = 0;
		}
	}
	
	
	
	
	# Get the allowed IPs of each ruleset
	my $ruleset_allowed_ip_command = "esxcli --formatter=csv network firewall ruleset allowedip list";
	my ($ruleset_allowed_ip_exit_status, $ruleset_allowed_ip_output) = $self->vmhost_os->execute($ruleset_allowed_ip_command);
	if (!defined($ruleset_allowed_ip_output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute command on VM host $vmhost_computer_name: $ruleset_allowed_ip_command");
		return;
	}
	elsif ($ruleset_allowed_ip_exit_status ne 0) {
		notify($ERRORS{'WARNING'}, 0, "failed to retrieve firewall ruleset allowed IP info from VM host $vmhost_computer_name, exit status: $ruleset_allowed_ip_exit_status, command:\n$ruleset_allowed_ip_command\noutput:\n" . join("\n", @$ruleset_allowed_ip_output));
		return 0;
	}
	
	# AllowedIPAddresses,Ruleset,
	# "152.1.4.152,10.25.7.2,10.25.11.104,10.25.0.241,10.25.0.242,10.25.0.243,10.25.0.244,10.25.0.245,10.25.0.246,10.25.1.178,",sshServer,
	# "All,",sshClient,
	# ...
	for my $line (@$ruleset_allowed_ip_output) {
		if ($line =~ /Ruleset/) {
			next;
		}
		
		my ($ip_address_string, $ruleset_name) = $line =~ /^"?(.+),"?,([^,]+),/g;
		if (!defined($ruleset_name)) {
			notify($ERRORS{'WARNING'}, 0, "failed to retrieve firewall ruleset allowed IP info from VM host $vmhost_computer_name, failed to parse line:\n$line");
			return;
		}
		
		my @ip_addresses = split(/,/, $ip_address_string);
		$ruleset_info->{$ruleset_name}{allowedip} = \@ip_addresses;
	}
	
	# Get the rule port information
	my $rule_list_command = "esxcli --formatter=csv network firewall ruleset rule list";
	my ($rule_list_exit_status, $rule_list_output) = $self->vmhost_os->execute($rule_list_command);
	if (!defined($rule_list_output)) {
		notify($ERRORS{'WARNING'}, 0, "failed to execute command on VM host $vmhost_computer_name: $rule_list_command");
		return;
	}
	elsif ($rule_list_exit_status ne 0) {
		notify($ERRORS{'WARNING'}, 0, "failed to retrieve firewall rule info from VM host $vmhost_computer_name, exit status: $rule_list_exit_status, command:\n$rule_list_command\noutput:\n" . join("\n", @$rule_list_output));
		return 0;
	}
	
	# Parse the header line
	# Direction,PortBegin,PortEnd,PortType,Protocol,Ruleset,
	my $rule_header_line = shift @$rule_list_output;
	my @rule_fields = split(/,/, $rule_header_line);
	my $rule_field_count = scalar(@rule_fields);
	
	# Inbound,22,22,Dst,TCP,sshServer,
	# Outbound,22,22,Dst,TCP,sshClient,
	# Outbound,0,65535,Dst,TCP,nfsClient,
	# Outbound,2049,2049,Dst,TCP,nfs41Client,
	for my $line (@$rule_list_output) {
		if ($line !~ /bound/) {
			next;
		}
		my @values = split(/,/, $line);
		my $rule = {};
		for (my $i = 0; $i < $rule_field_count; $i++) {
			my $field = $rule_fields[$i];
			my $value = $values[$i];
			$rule->{$field} = $value;
		}
		my $ruleset_name = $rule->{Ruleset};
		delete $rule->{Ruleset};
		
		push @{$ruleset_info->{$ruleset_name}{rules}}, $rule;
	}
	
	notify($ERRORS{'OK'}, 0, "retrieved firewall ruleset info from VM host $vmhost_computer_name:\n" . format_data($ruleset_info));
	$ENV->{firewall_ruleset_info} = $ruleset_info;
	return $ruleset_info;
}