Revision 8346937a
Added by Dominic Cleal about 8 years ago
README.md | ||
---|---|---|
|
||
## Compatibility
|
||
|
||
This module only supports Smart Proxy 1.6 or higher as of version 2.0, as the
|
||
This module only supports Smart Proxy 1.11 or higher as of version 3.0, as the
|
||
configuration layout changed significantly.
|
||
|
||
To configure older versions of the Smart Proxy (1.5 or older), use an older
|
||
version of this module (1.x).
|
||
|
||
Since version 1.10 the DNS configuration files are split. If you wish to use
|
||
prior versions with DNS, then you must set `dns_split_config_files` to `false`.
|
||
|
||
Since version 1.11 the DHCP configuration files are split. If you wish to use
|
||
prior versions with DHCP, then you must set `dhcp_split_config_files` to `false`.
|
||
To configure older versions of the Smart Proxy (1.5 to 1.10), use version 2.x
|
||
of this module.
|
||
|
||
# Contributing
|
||
|
manifests/config.pp | ||
---|---|---|
enabled => $::foreman_proxy::dhcp,
|
||
listen_on => $::foreman_proxy::dhcp_listen_on,
|
||
}
|
||
if $::foreman_proxy::dhcp_split_config_files {
|
||
foreman_proxy::settings_file { 'dhcp_isc':
|
||
module => false,
|
||
}
|
||
foreman_proxy::settings_file { 'dhcp_isc':
|
||
module => false,
|
||
}
|
||
foreman_proxy::settings_file { 'dns':
|
||
enabled => $::foreman_proxy::dns,
|
||
listen_on => $::foreman_proxy::dns_listen_on,
|
||
}
|
||
if $::foreman_proxy::dns_split_config_files {
|
||
foreman_proxy::settings_file { ['dns_nsupdate', 'dns_nsupdate_gss']:
|
||
module => false,
|
||
}
|
||
foreman_proxy::settings_file { ['dns_nsupdate', 'dns_nsupdate_gss']:
|
||
module => false,
|
||
}
|
||
foreman_proxy::settings_file { 'puppet':
|
||
enabled => $::foreman_proxy::puppetrun,
|
manifests/init.pp | ||
---|---|---|
#
|
||
# $bind_host:: Host to bind ports to, e.g. *, localhost, 0.0.0.0
|
||
#
|
||
# $port:: Port to listen on (deprecated in favor of $ssl_port and $http_port)
|
||
# type:integer
|
||
#
|
||
# $http:: Enable HTTP
|
||
# type:boolean
|
||
#
|
||
... | ... | |
#
|
||
# $tftp_manage_wget:: If enabled will install the wget package
|
||
# type:boolean
|
||
# $tftp_syslinux_root:: Directory that hold syslinux files (deprecated, see $tftp_syslinux_filenames)
|
||
#
|
||
# $tftp_syslinux_files:: Syslinux files to install on TFTP (copied from $tftp_syslinux_root,
|
||
# deprecated, see $tftp_syslinux_filenames)
|
||
# type:array
|
||
#
|
||
# $tftp_syslinux_filenames:: Syslinux files to install on TFTP (full paths)
|
||
# type:array
|
||
#
|
||
... | ... | |
# $dhcp:: Enable DHCP feature
|
||
# type:boolean
|
||
#
|
||
# $dhcp_split_config_files:: Split DHCP configuration files. This is needed since version 1.11.
|
||
# type:boolean
|
||
#
|
||
# $dhcp_listen_on:: DHCP proxy to listen on https, http, or both
|
||
#
|
||
# $dhcp_managed:: DHCP is managed by Foreman proxy
|
||
... | ... | |
#
|
||
# $dhcp_provider:: DHCP provider
|
||
#
|
||
# $dhcp_vendor:: DHCP vendor (deprecated, use dhcp_provider)
|
||
#
|
||
# $dhcp_option_domain:: DHCP use the dhcpd config option domain-name
|
||
# type:array
|
||
#
|
||
... | ... | |
# $dns:: Enable DNS feature
|
||
# type:boolean
|
||
#
|
||
# $dns_split_config_files:: Split DNS configuration files. This is needed since version 1.10.
|
||
# type:boolean
|
||
#
|
||
# $dns_listen_on:: DNS proxy to listen on https, http, or both
|
||
#
|
||
# $dns_managed:: DNS is managed by Foreman proxy
|
||
... | ... | |
$ensure_packages_version = $foreman_proxy::params::ensure_packages_version,
|
||
$plugin_version = $foreman_proxy::params::plugin_version,
|
||
$bind_host = $foreman_proxy::params::bind_host,
|
||
$port = $foreman_proxy::params::port,
|
||
$http_port = $foreman_proxy::params::http_port,
|
||
$ssl_port = $foreman_proxy::params::ssl_port,
|
||
$dir = $foreman_proxy::params::dir,
|
||
... | ... | |
$tftp = $foreman_proxy::params::tftp,
|
||
$tftp_listen_on = $foreman_proxy::params::tftp_listen_on,
|
||
$tftp_manage_wget = $foreman_proxy::params::tftp_manage_wget,
|
||
$tftp_syslinux_root = $foreman_proxy::params::tftp_syslinux_root,
|
||
$tftp_syslinux_files = $foreman_proxy::params::tftp_syslinux_files,
|
||
$tftp_syslinux_filenames = $foreman_proxy::params::tftp_syslinux_filenames,
|
||
$tftp_root = $foreman_proxy::params::tftp_root,
|
||
$tftp_dirs = $foreman_proxy::params::tftp_dirs,
|
||
$tftp_servername = $foreman_proxy::params::tftp_servername,
|
||
$dhcp = $foreman_proxy::params::dhcp,
|
||
$dhcp_split_config_files = $foreman_proxy::params::dhcp_split_config_files,
|
||
$dhcp_listen_on = $foreman_proxy::params::dhcp_listen_on,
|
||
$dhcp_managed = $foreman_proxy::params::dhcp_managed,
|
||
$dhcp_provider = $foreman_proxy::params::dhcp_provider,
|
||
$dhcp_vendor = $foreman_proxy::params::dhcp_vendor,
|
||
$dhcp_option_domain = $foreman_proxy::params::dhcp_option_domain,
|
||
$dhcp_interface = $foreman_proxy::params::dhcp_interface,
|
||
$dhcp_gateway = $foreman_proxy::params::dhcp_gateway,
|
||
... | ... | |
$dhcp_key_secret = $foreman_proxy::params::dhcp_key_secret,
|
||
$dhcp_omapi_port = $foreman_proxy::params::dhcp_omapi_port,
|
||
$dns = $foreman_proxy::params::dns,
|
||
$dns_split_config_files = $foreman_proxy::params::dns_split_config_files,
|
||
$dns_listen_on = $foreman_proxy::params::dns_listen_on,
|
||
$dns_managed = $foreman_proxy::params::dns_managed,
|
||
$dns_provider = $foreman_proxy::params::dns_provider,
|
||
... | ... | |
$puppet_cache_location = $foreman_proxy::params::puppet_cache_location,
|
||
) inherits foreman_proxy::params {
|
||
|
||
# Port is deprecated
|
||
if $port {
|
||
warning("${::hostname}: foreman_proxy::port is deprecated; please use http_port or ssl_port instead")
|
||
$real_ssl = $ssl
|
||
$real_http = !$ssl
|
||
$real_http_port = $port
|
||
$real_https_port = $port
|
||
} else {
|
||
$real_ssl = $ssl
|
||
$real_http = $http
|
||
$real_http_port = $http_port
|
||
$real_https_port = $ssl_port
|
||
}
|
||
|
||
# Validate misc params
|
||
validate_string($bind_host)
|
||
validate_bool($ssl, $manage_sudoersd, $use_sudoersd, $register_in_foreman)
|
||
... | ... | |
}
|
||
|
||
# Validate dhcp params
|
||
validate_bool($dhcp_managed, $dhcp_split_config_files)
|
||
validate_bool($dhcp_managed)
|
||
validate_array($dhcp_option_domain)
|
||
validate_integer($dhcp_omapi_port)
|
||
validate_string($dhcp_provider, $dhcp_server)
|
||
if $dhcp_vendor {
|
||
validate_string($dhcp_vendor)
|
||
warning("${::hostname}: foreman_proxy::dhcp_vendor is deprecated; please use dhcp_provider instead")
|
||
}
|
||
# dhcp_vendor is deprecated in favour of dhcp_provider
|
||
$dhcp_provider_real = pick($dhcp_vendor, $dhcp_provider)
|
||
|
||
# Validate dns params
|
||
validate_bool($dns, $dns_split_config_files)
|
||
validate_bool($dns)
|
||
validate_string($dns_interface, $dns_provider, $dns_reverse, $dns_server, $keyfile)
|
||
validate_array($dns_forwarders)
|
||
|
manifests/params.pp | ||
---|---|---|
|
||
# Enable listening on http
|
||
$bind_host = '*'
|
||
$port = undef # deprecated in favor of $ssl_port/$http_port
|
||
$http = false
|
||
$http_port = '8000'
|
||
|
||
... | ... | |
$tftp_dirs = ["${tftp_root}/pxelinux.cfg","${tftp_root}/boot","${tftp_root}/ztp.cfg","${tftp_root}/poap.cfg"]
|
||
$tftp_servername = undef
|
||
|
||
# TODO: remove these on the next major version bump
|
||
$tftp_syslinux_root = undef
|
||
$tftp_syslinux_files = undef
|
||
|
||
# DHCP settings - requires optional DHCP puppet module
|
||
$dhcp = false
|
||
$dhcp_split_config_files = true # smart-proxy 1.11+
|
||
$dhcp_listen_on = 'https'
|
||
$dhcp_managed = true
|
||
$dhcp_provider = 'isc'
|
||
$dhcp_vendor = undef
|
||
$dhcp_interface = 'eth0'
|
||
$dhcp_gateway = '192.168.100.1'
|
||
$dhcp_range = false
|
||
... | ... | |
|
||
# DNS settings - requires optional DNS puppet module
|
||
$dns = false
|
||
$dns_split_config_files = true # smart-proxy 1.10+
|
||
$dns_listen_on = 'https'
|
||
$dns_managed = true
|
||
$dns_provider = 'nsupdate'
|
manifests/tftp.pp | ||
---|---|---|
recurse => true;
|
||
}
|
||
|
||
if $foreman_proxy::tftp_syslinux_files {
|
||
# TODO: remove on the next major version bump
|
||
foreman_proxy::tftp::sync_file{$foreman_proxy::tftp_syslinux_files:
|
||
source_path => $foreman_proxy::tftp_syslinux_root,
|
||
target_path => $foreman_proxy::tftp_root,
|
||
require => Class['tftp::install'];
|
||
}
|
||
|
||
warning('foreman_proxy::tftp_syslinux_files is deprecated in favour of foreman_proxy::tftp_syslinux_filenames and will be removed')
|
||
} else {
|
||
foreman_proxy::tftp::copy_file{$foreman_proxy::tftp_syslinux_filenames:
|
||
target_path => $foreman_proxy::tftp_root,
|
||
require => Class['tftp::install'];
|
||
}
|
||
foreman_proxy::tftp::copy_file{$foreman_proxy::tftp_syslinux_filenames:
|
||
target_path => $foreman_proxy::tftp_root,
|
||
require => Class['tftp::install'];
|
||
}
|
||
|
||
if $foreman_proxy::tftp_manage_wget {
|
manifests/tftp/sync_file.pp | ||
---|---|---|
# Sync a TFTP file
|
||
# TODO: remove on the next major version bump
|
||
define foreman_proxy::tftp::sync_file(
|
||
$source_path,
|
||
$target_path
|
||
) {
|
||
warning('foreman_proxy::tftp::sync_file is deprecated and will be removed')
|
||
|
||
file {"${target_path}/${name}":
|
||
ensure => file,
|
||
source => "${source_path}/${name}",
|
||
}
|
||
|
||
}
|
spec/classes/foreman_proxy__config__spec.rb | ||
---|---|---|
end
|
||
end
|
||
|
||
context 'with deprecated parameters' do
|
||
context 'with ssl => true' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
ssl => true,
|
||
port => 1234,
|
||
}'
|
||
end
|
||
|
||
it 'should use port for ssl' do
|
||
verify_contents(catalogue, "#{etc_dir}/foreman-proxy/settings.yml", [
|
||
':https_port: 1234',
|
||
'#:http_port: 1234',
|
||
])
|
||
end
|
||
end
|
||
|
||
context 'with ssl => false' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
ssl => false,
|
||
port => 1234,
|
||
}'
|
||
end
|
||
|
||
it 'should use port for http' do
|
||
verify_contents(catalogue, "#{etc_dir}/foreman-proxy/settings.yml", [
|
||
'#:https_port: 1234',
|
||
':http_port: 1234',
|
||
])
|
||
end
|
||
end
|
||
end
|
||
|
||
context 'when dns_provider => nsupdate_gss' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
... | ... | |
end
|
||
end
|
||
|
||
context 'when dns_split_config_files => false' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
dns_split_config_files => false,
|
||
}'
|
||
end
|
||
|
||
it 'should not split the dns config' do
|
||
dns_key = case facts[:osfamily]
|
||
when 'Debian'
|
||
'/etc/bind/rndc.key'
|
||
when 'FreeBSD', 'Dragonfly'
|
||
'/usr/local/etc/namedb/rndc.key'
|
||
else
|
||
'/etc/rndc.key'
|
||
end
|
||
|
||
verify_exact_contents(catalogue, "#{etc_dir}/foreman-proxy/settings.d/dns.yml", [
|
||
'---',
|
||
':enabled: false',
|
||
':dns_provider: nsupdate',
|
||
':dns_server: 127.0.0.1',
|
||
':dns_ttl: 86400',
|
||
":dns_key: #{dns_key}",
|
||
])
|
||
|
||
should_not contain_file("#{etc_dir}/foreman-proxy/settings.d/dns_nsupdate.yml")
|
||
should_not contain_file("#{etc_dir}/foreman-proxy/settings.d/dns_nsupdate_gss.yml")
|
||
end
|
||
end
|
||
|
||
context 'when puppetrun_provider => puppetrun' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
... | ... | |
':omapi_port: 7911',
|
||
])
|
||
end
|
||
|
||
context 'with dhcp_vendor' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
dhcp => true,
|
||
dhcp_vendor => "native_ms",
|
||
dhcp_managed => false,
|
||
}'
|
||
end
|
||
|
||
it 'should set :use_provider' do
|
||
verify_contents(catalogue, "#{etc_dir}/foreman-proxy/settings.d/dhcp.yml", [
|
||
':use_provider: dhcp_native_ms',
|
||
])
|
||
end
|
||
end
|
||
|
||
context 'when dhcp_split_config_files => false' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
dhcp => true,
|
||
dhcp_managed => false,
|
||
dhcp_split_config_files => false,
|
||
}'
|
||
end
|
||
|
||
it 'should not split the dhcp config' do
|
||
verify_exact_contents(catalogue, "#{etc_dir}/foreman-proxy/settings.d/dhcp.yml", [
|
||
'---',
|
||
':enabled: https',
|
||
':dhcp_vendor: isc',
|
||
':dhcp_server: 127.0.0.1',
|
||
":dhcp_config: #{dhcp_config}",
|
||
":dhcp_leases: #{dhcp_leases}",
|
||
':dhcp_omapi_port: 7911',
|
||
])
|
||
|
||
should_not contain_file("#{etc_dir}/foreman-proxy/settings.d/dhcp_isc.yml")
|
||
end
|
||
|
||
context 'with dhcp_vendor' do
|
||
let :pre_condition do
|
||
'class {"foreman_proxy":
|
||
dhcp => true,
|
||
dhcp_vendor => "native_ms",
|
||
dhcp_managed => false,
|
||
dhcp_split_config_files => false,
|
||
}'
|
||
end
|
||
|
||
it 'should set :dhcp_vendor' do
|
||
verify_contents(catalogue, "#{etc_dir}/foreman-proxy/settings.d/dhcp.yml", [
|
||
':dhcp_vendor: native_ms',
|
||
])
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
context 'with ssl_disabled_ciphers' do
|
templates/dhcp.yml.erb | ||
---|---|---|
<% dhcp_split_files = scope.lookupvar("foreman_proxy::dhcp_split_config_files") -%>
|
||
---
|
||
# Enable DHCP management
|
||
# Can be true, false, or http/https to enable just one of the protocols
|
||
:enabled: <%= @module_enabled %>
|
||
|
||
# valid providers:
|
||
# - <%= "dhcp_" if dhcp_split_files %>isc (ISC dhcp server)
|
||
# - <%= "dhcp_" if dhcp_split_files %>native_ms (Microsoft native implementation)
|
||
# - <%= "dhcp_" if dhcp_split_files %>virsh (simple implementation for libvirt)
|
||
<% if dhcp_split_files -%>
|
||
:use_provider: dhcp_<%= scope.lookupvar("foreman_proxy::dhcp_provider_real") %>
|
||
# - <%= "dhcp_" %>isc (ISC dhcp server)
|
||
# - <%= "dhcp_" %>native_ms (Microsoft native implementation)
|
||
# - <%= "dhcp_" %>virsh (simple implementation for libvirt)
|
||
:use_provider: dhcp_<%= scope.lookupvar("foreman_proxy::dhcp_provider") %>
|
||
:server: <%= scope.lookupvar("foreman_proxy::dhcp_server") %>
|
||
# subnets restricts the subnets queried to a subset, to reduce the query time.
|
||
#:subnets: [192.168.205.0/255.255.255.128, 192.168.205.128/255.255.255.128]
|
||
<% else -%>
|
||
<% if scope.lookupvar("foreman_proxy::dhcp") == true -%>
|
||
:dhcp_vendor: <%= scope.lookupvar("foreman_proxy::dhcp_provider_real") %>
|
||
:dhcp_server: <%= scope.lookupvar("foreman_proxy::dhcp_server") %>
|
||
:dhcp_config: <%= scope.lookupvar("foreman_proxy::dhcp_config") %>
|
||
:dhcp_leases: <%= scope.lookupvar("foreman_proxy::dhcp_leases") %>
|
||
<% unless [nil, :undefined, :undef, ''].include?(scope.lookupvar("foreman_proxy::dhcp_key_name")) ||
|
||
[nil, :undefined, :undef, ''].include?(scope.lookupvar("foreman_proxy::dhcp_key_secret")) -%>
|
||
:dhcp_key_name: <%= scope.lookupvar("foreman_proxy::dhcp_key_name") %>
|
||
:dhcp_key_secret: <%= scope.lookupvar("foreman_proxy::dhcp_key_secret") %>
|
||
<% else -%>
|
||
#:dhcp_key_name: secret_key_name
|
||
#:dhcp_key_secret: secret_key
|
||
<% end -%>
|
||
:dhcp_omapi_port: <%= scope.lookupvar("foreman_proxy::dhcp_omapi_port") %>
|
||
<% else -%>
|
||
# The vendor can be either isc or native_ms
|
||
:dhcp_vendor: isc
|
||
#:dhcp_server: 127.0.0.1
|
||
# dhcp_subnets is a Native MS implementation setting. It restricts the subnets queried to a
|
||
# subset, so as to reduce the query time.
|
||
#:dhcp_subnets: [192.168.205.0/255.255.255.128, 192.168.205.128/255.255.255.128]
|
||
# Settings for Ubuntu ISC
|
||
#:dhcp_config: /etc/dhcp3/dhcpd.conf
|
||
#:dhcp_leases: /var/lib/dhcp3/dhcpd.leases
|
||
# Settings for Redhat ISC
|
||
#:dhcp_config: /etc/dhcpd.conf
|
||
#:dhcp_leases: /var/lib/dhcpd/dhcpd.leases
|
||
#:dhcp_key_name: secret_key_name
|
||
#:dhcp_key_secret: secret_key
|
||
#:dhcp_omapi_port: 7911
|
||
<% end -%>
|
||
<% end -%>
|
templates/dns.yml.erb | ||
---|---|---|
<% dns_split_files = scope.lookupvar("foreman_proxy::dns_split_config_files") -%>
|
||
---
|
||
# DNS management
|
||
:enabled: <%= @module_enabled %>
|
||
# valid providers:
|
||
# <%= "dns_" if dns_split_files %>dnscmd (Microsoft Windows native implementation)
|
||
# <%= "dns_" if dns_split_files %>nsupdate
|
||
# <%= "dns_" if dns_split_files %>nsupdate_gss (for GSS-TSIG support)
|
||
# <%= "dns_" if dns_split_files %>virsh (simple implementation for libvirt)
|
||
<% if dns_split_files -%>
|
||
# <%= "dns_" %>dnscmd (Microsoft Windows native implementation)
|
||
# <%= "dns_" %>nsupdate
|
||
# <%= "dns_" %>nsupdate_gss (for GSS-TSIG support)
|
||
# <%= "dns_" %>virsh (simple implementation for libvirt)
|
||
:use_provider: dns_<%= scope.lookupvar("foreman_proxy::dns_provider") %>
|
||
# use this setting if you want to override default TTL setting (86400)
|
||
:dns_ttl: <%= scope.lookupvar("foreman_proxy::dns_ttl") %>
|
||
<% else -%>
|
||
:dns_provider: <%= scope.lookupvar("foreman_proxy::dns_provider") %>
|
||
# use this setting if you are managing a dns server which is not localhost though this proxy
|
||
:dns_server: <%= scope.lookupvar("foreman_proxy::dns_server") %>
|
||
# use this setting if you want to override default TTL setting (86400)
|
||
:dns_ttl: <%= scope.lookupvar("foreman_proxy::dns_ttl") %>
|
||
# use dns_tsig_* for GSS-TSIG updates using Kerberos. Required for Windows MS DNS with
|
||
# Secure Dynamic Updates, or BIND as used in FreeIPA. Set dns_provider to nsupdate_gss.
|
||
<%if scope.lookupvar("foreman_proxy::dns_provider") == 'nsupdate_gss' -%>
|
||
:dns_tsig_keytab: <%= scope.lookupvar("foreman_proxy::dns_tsig_keytab") %>
|
||
:dns_tsig_principal: <%= scope.lookupvar("foreman_proxy::dns_tsig_principal") %>
|
||
# dns_key must be disabled if nsupdate_gss is used
|
||
#:dns_key: <%= scope.lookupvar("foreman_proxy::keyfile") %>
|
||
<% else -%>
|
||
:dns_key: <%= scope.lookupvar("foreman_proxy::keyfile") %>
|
||
#:dns_tsig_keytab: /usr/share/foreman-proxy/dns.keytab
|
||
#:dns_tsig_principal: DNS/host.example.com@EXAMPLE.COM
|
||
<% end -%>
|
||
<% end -%>
|
templates/settings.yml.erb | ||
---|---|---|
:settings_directory: <%= scope.lookupvar("foreman_proxy::etc") -%>/foreman-proxy/settings.d
|
||
|
||
# SSL Setup
|
||
<% ssl = scope.lookupvar("foreman_proxy::real_ssl") -%>
|
||
<% http = scope.lookupvar("foreman_proxy::real_http") -%>
|
||
<% ssl = scope.lookupvar("foreman_proxy::ssl") -%>
|
||
<% http = scope.lookupvar("foreman_proxy::http") -%>
|
||
|
||
# if enabled, all communication would be verified via SSL
|
||
# NOTE that both certificates need to be signed by the same CA in order for this to work
|
||
... | ... | |
# https is enabled if certificate, CA certificate, and private key are present in locations specifed by
|
||
# ssl_certificate, ssl_ca_file, and ssl_private_key correspondingly
|
||
# default values for https_port is 8443
|
||
<%= '#' unless ssl -%>:https_port: <%= scope.lookupvar("foreman_proxy::real_https_port") %>
|
||
<%= '#' unless http -%>:http_port: <%= scope.lookupvar("foreman_proxy::real_http_port") %>
|
||
<%= '#' unless ssl -%>:https_port: <%= scope.lookupvar("foreman_proxy::ssl_port") %>
|
||
<%= '#' unless http -%>:http_port: <%= scope.lookupvar("foreman_proxy::http_port") %>
|
||
|
||
# shared options for virsh DNS/DHCP provider
|
||
:virsh_network: <%= scope.lookupvar("foreman_proxy::virsh_network") %>
|
Also available in: Unified diff
Remove deprecated features and pre-1.11 support