Improve firewall rules for Fuel Master
Replaces hardcoded functions to create iptables rules for Nailgun and Cobbler with firewall module managed rules. Restricts network access to Fuel Master for all services (except Fuel Web/API) to Admin Network, plus restricts postgres to localhost access only. blueprint master-node-iptables-ruleset Change-Id: Ib5d0c554bf97957c45b206b8bf4f6e64c9be109f
This commit is contained in:
parent
967c047bf5
commit
3a418e3420
@ -13,29 +13,9 @@
|
||||
# under the License.
|
||||
|
||||
|
||||
class cobbler::iptables {
|
||||
|
||||
define access_to_cobbler_port($port, $protocol='tcp') {
|
||||
$rule = "-p $protocol -m state --state NEW -m $protocol --dport $port -j ACCEPT"
|
||||
case $operatingsystem {
|
||||
/(?i)(centos|redhat)/: {
|
||||
exec { "access_to_cobbler_${protocol}_port: $port":
|
||||
command => "iptables -t filter -I INPUT 1 $rule; \
|
||||
/etc/init.d/iptables save",
|
||||
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\"",
|
||||
path => '/usr/bin:/bin:/usr/sbin:/sbin',
|
||||
}
|
||||
}
|
||||
/(?i)(debian|ubuntu)/: {
|
||||
exec { "access_to_cobbler_${protocol}_port: $port":
|
||||
command => "iptables -t filter -I INPUT 1 $rule; \
|
||||
iptables-save -c > /etc/iptables.rules",
|
||||
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\"",
|
||||
path => '/usr/bin:/bin:/usr/sbin:/sbin',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class cobbler::iptables (
|
||||
$chain = "INPUT",
|
||||
) {
|
||||
|
||||
case $operatingsystem {
|
||||
/(?i)(debian|ubuntu)/:{
|
||||
@ -54,32 +34,40 @@ class cobbler::iptables {
|
||||
}
|
||||
}
|
||||
|
||||
# HERE IS IPTABLES RULES TO MAKE COBBLER AVAILABLE FROM OUTSIDE
|
||||
# https://github.com/cobbler/cobbler/wiki/Using%20Cobbler%20Import
|
||||
# SSH
|
||||
access_to_cobbler_port { "ssh": port => '22' }
|
||||
# DNS
|
||||
access_to_cobbler_port { "dns_tcp": port => '53' }
|
||||
access_to_cobbler_port { "dns_udp": port => '53', protocol => 'udp' }
|
||||
# DHCP
|
||||
access_to_cobbler_port { "dhcp_67": port => '67', protocol => 'udp' }
|
||||
access_to_cobbler_port { "dhcp_68": port => '68', protocol => 'udp' }
|
||||
# SQUID PROXY
|
||||
access_to_cobbler_port { "http_3128": port => '3128',protocol => 'tcp' }
|
||||
# PXE
|
||||
access_to_cobbler_port { "pxe_4011": port => '4011',protocol => 'udp' }
|
||||
# TFTP
|
||||
access_to_cobbler_port { "tftp_tcp": port => '69' }
|
||||
access_to_cobbler_port { "tftp_udp": port => '69', protocol => 'udp' }
|
||||
# NTP
|
||||
access_to_cobbler_port { "ntp_udp": port => '123', protocol => 'udp' }
|
||||
# HTTP/HTTPS
|
||||
access_to_cobbler_port { "http": port => '80' }
|
||||
access_to_cobbler_port { "https": port => '443'}
|
||||
# SYSLOG FOR COBBLER
|
||||
access_to_cobbler_port { "syslog_tcp": port => '25150'}
|
||||
# xmlrpc API
|
||||
access_to_cobbler_port { "xmlrpc_api": port => '25151' }
|
||||
|
||||
|
||||
firewall { '101 dns_tcp':
|
||||
chain => $chain,
|
||||
port => '53',
|
||||
proto => 'tcp',
|
||||
action => 'accept',
|
||||
}
|
||||
firewall { '102 dns_udp':
|
||||
chain => $chain,
|
||||
port => '53',
|
||||
proto => 'udp',
|
||||
action => 'accept',
|
||||
}
|
||||
firewall { '103 dhcp':
|
||||
chain => $chain,
|
||||
port => ['67','68'],
|
||||
proto => 'udp',
|
||||
action => 'accept',
|
||||
}
|
||||
firewall { '104 tftp':
|
||||
chain => $chain,
|
||||
port => '69',
|
||||
proto => 'udp',
|
||||
action => 'accept',
|
||||
}
|
||||
firewall { '110 squidproxy':
|
||||
chain => $chain,
|
||||
port => '3128',
|
||||
proto => 'tcp',
|
||||
action => 'accept',
|
||||
}
|
||||
firewall { '111 cobbler_web':
|
||||
chain => $chain,
|
||||
port => ['80','443'],
|
||||
proto => 'tcp',
|
||||
action => 'accept',
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
class docker::dockerctl (
|
||||
$bin_dir = '/usr/bin',
|
||||
$share_dir = '/usr/share/dockerctl',
|
||||
$config_dir = '/etc/dockerctl',
|
||||
$profile_dir = '/etc/profile.d',
|
||||
$bin_dir = '/usr/bin',
|
||||
$share_dir = '/usr/share/dockerctl',
|
||||
$config_dir = '/etc/dockerctl',
|
||||
$profile_dir = '/etc/profile.d',
|
||||
$admin_ipaddress = $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
||||
$release,
|
||||
$production,
|
||||
) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
class docker (
|
||||
$admin_ipaddress = $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
||||
$limit = "102400",
|
||||
$docker_package = "docker-io",
|
||||
$docker_service = "docker",
|
||||
|
@ -9,6 +9,9 @@ SOURCE_DIR="${DOCKER_ROOT}/sources"
|
||||
#SUPERVISOR_CONF_DIR="${docker_root}/supervisor"
|
||||
#SUPERVISOR_CONF_DIR="<%= @config_dir %>/supervisor/"
|
||||
ASTUTE_YAML="<%= @astute_settings_file %>"
|
||||
ADMIN_IP="<%= @admin_ipaddress %>"
|
||||
LOCAL_IP="127.0.0.1"
|
||||
|
||||
#Version of Fuel to deploy
|
||||
VERSION=$(awk '/release/{gsub(/"/, "");print $2}' /etc/fuel/version.yaml || echo <%= @release %>)
|
||||
IMAGE_PREFIX="fuel"
|
||||
@ -60,17 +63,20 @@ declare -A CONTAINER_OPTIONS
|
||||
base_opts="-t"
|
||||
FOREGROUND="-i"
|
||||
BACKGROUND="-d"
|
||||
CONTAINER_OPTIONS["cobbler"]="-p 53:53/udp -p 69:69/udp -p 80:80 -p 443:443 --privileged $base_opts"
|
||||
CONTAINER_OPTIONS["postgres"]="-p 5432:5432 $base_opts"
|
||||
CONTAINER_OPTIONS["rabbitmq"]="-p 5672:5672 -p 4369:4369 -p 15672:15672 -p 61613:61613 $base_opts"
|
||||
CONTAINER_OPTIONS["rsync"]="-p 873:873 $base_opts"
|
||||
BIND_ALL=""
|
||||
BIND_ADMIN="${ADMIN_IP}:"
|
||||
BIND_LOCAL="${LOCAL_IP}:"
|
||||
CONTAINER_OPTIONS["cobbler"]="-p ${BIND_ADMIN}53:53/udp -p ${BIND_LOCAL}53:53/udp -p ${BIND_ADMIN}69:69/udp -p ${BIND_LOCAL}69:69/udp -p ${BIND_ALL}80:80 -p ${BIND_ALL}443:443 --privileged $base_opts"
|
||||
CONTAINER_OPTIONS["postgres"]="-p ${BIND_ADMIN}5432:5432 -p ${BIND_LOCAL}5432:5432 $base_opts"
|
||||
CONTAINER_OPTIONS["rabbitmq"]="-p ${BIND_ADMIN}5672:5672 -p ${BIND_LOCAL}5672:5672 -p ${BIND_ADMIN}4369:4369 -p ${BIND_LOCAL}4369:4369 -p ${BIND_ADMIN}15672:15672 -p ${BIND_LOCAL}15672:15672 -p ${BIND_ADMIN}61613:61613 -p ${BIND_LOCAL}61613:61613 $base_opts"
|
||||
CONTAINER_OPTIONS["rsync"]="-p ${BIND_ADMIN}873:873 -p ${BIND_LOCAL}873:873 $base_opts"
|
||||
CONTAINER_OPTIONS["astute"]="$base_opts"
|
||||
CONTAINER_OPTIONS["nailgun"]="-v /etc/nailgun -p 8001:8001 $base_opts"
|
||||
CONTAINER_OPTIONS["ostf"]="-p 8777:8777 $base_opts"
|
||||
CONTAINER_OPTIONS["nginx"]="-p 8000:8000 -p 8080:8080 $base_opts"
|
||||
CONTAINER_OPTIONS["rsyslog"]="--privileged -p 514:514 -p 514:514/udp -p 25150 $base_opts"
|
||||
CONTAINER_OPTIONS["nailgun"]="-v /etc/nailgun -p ${BIND_ADMIN}8001:8001 -p ${BIND_LOCAL}8001:8001 $base_opts"
|
||||
CONTAINER_OPTIONS["ostf"]="-p ${BIND_ADMIN}8777:8777 -p ${BIND_LOCAL}8777:8777 $base_opts"
|
||||
CONTAINER_OPTIONS["nginx"]="-p ${BIND_ALL}8000:8000 -p ${BIND_ALL}8080:8080 $base_opts"
|
||||
CONTAINER_OPTIONS["rsyslog"]="--privileged -p ${BIND_ADMIN}514:514 -p ${BIND_LOCAL}514:514 -p ${BIND_ADMIN}514:514/udp -p ${BIND_LOCAL}514:514/udp -p ${BIND_ADMIN}25150:25150 -p ${BIND_LOCAL}25150:25150 $base_opts"
|
||||
CONTAINER_OPTIONS["mcollective"]="--privileged $base_opts"
|
||||
CONTAINER_OPTIONS["keystone"]="-p 5000:5000 -p 35357:35357 $base_opts"
|
||||
CONTAINER_OPTIONS["keystone"]="-p ${BIND_ALL}5000:5000 -p ${BIND_ALL}35357:35357 $base_opts"
|
||||
|
||||
######
|
||||
#DRAFT: Dependency of volumes for deployment
|
||||
|
@ -106,20 +106,20 @@ function check_ready {
|
||||
failure=0
|
||||
echo "checking container $1"
|
||||
case $1 in
|
||||
nailgun) retry_checker '[ $(curl --connect-timeout 1 -s -w %{http_code} http://127.0.0.1:8000/api/version -o /dev/null) = "200" ]' ;;
|
||||
ostf) retry_checker '[ $(curl --connect-timeout 1 -s -w '%{http_code}' http://127.0.0.1:8000/ostf/not_found -o /dev/null) = "404" ]' ;;
|
||||
nailgun) retry_checker "grep -q 200 < <(curl --connect-timeout 1 -s -w %{http_code} http://$ADMIN_IP:8000/api/version -o /dev/null)" ;;
|
||||
ostf) retry_checker "grep -q 404 < <(curl --connect-timeout 1 -s -w '%{http_code}' http://$ADMIN_IP:8000/ostf/not_found -o /dev/null)" ;;
|
||||
#NOTICE: Cobbler console tool does not comply unix conversation: 'cobbler profile find' always return 0 as exit code
|
||||
cobbler) retry_checker "shell_container cobbler ps aux | grep -q 'cobblerd -F'"
|
||||
retry_checker "shell_container cobbler cobbler profile find --name=centos* | grep -q centos"
|
||||
retry_checker "shell_container cobbler cobbler profile find --name=ubuntu* | grep -q ubuntu"
|
||||
retry_checker "shell_container cobbler cobbler profile find --name=bootstrap* | grep -q bootstrap" ;;
|
||||
rabbitmq) retry_checker "curl -f -L -i -u \"$astute_user:$astute_password\" http://127.0.0.1:15672/api/nodes 1>/dev/null 2>&1"
|
||||
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'mcollective_broadcast'"
|
||||
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'mcollective_directed'" ;;
|
||||
postgres) retry_checker "PGPASSWORD=$postgres_nailgun_password shell_container postgres psql -h 127.0.0.1 -U \"$postgres_nailgun_user\" \"$postgres_nailgun_dbname\" -c '\copyright' 2>&1 1>/dev/null" ;;
|
||||
rabbitmq) retry_checker "curl -f -L -i -u \"$astute_user:$astute_password\" http://$ADMIN_IP:15672/api/nodes 1>/dev/null 2>&1"
|
||||
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'mcollective_broadcast'"
|
||||
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'mcollective_directed'" ;;
|
||||
postgres) retry_checker "PGPASSWORD=$postgres_nailgun_password shell_container postgres psql -h $ADMIN_IP -U \"$postgres_nailgun_user\" \"$postgres_nailgun_dbname\" -c '\copyright' 2>&1 1>/dev/null" ;;
|
||||
astute) retry_checker "shell_container astute ps aux | grep -q 'astuted'"
|
||||
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'nailgun'"
|
||||
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'naily_service'" ;;
|
||||
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'nailgun'"
|
||||
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'naily_service'" ;;
|
||||
rsync) retry_checker "shell_container rsync netstat -ntl | grep -q 873" ;;
|
||||
rsyslog) retry_checker "shell_container rsyslog netstat -nl | grep -q 514" ;;
|
||||
mcollective) retry_checker "shell_container mcollective ps aux | grep -q mcollectived" ;;
|
||||
|
@ -34,8 +34,9 @@ class { "openstack::clocksync":
|
||||
}
|
||||
|
||||
class { "docker::dockerctl":
|
||||
release => $::fuel_version['VERSION']['release'],
|
||||
production => $production,
|
||||
release => $::fuel_version['VERSION']['release'],
|
||||
production => $production,
|
||||
admin_ipaddress => $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
|
||||
}
|
||||
class { "docker": }
|
||||
|
||||
|
@ -1,27 +1,179 @@
|
||||
class nailgun::iptables {
|
||||
|
||||
define access_to_nailgun_port($port, $protocol='tcp') {
|
||||
$rule = "-p $protocol -m state --state NEW -m $protocol --dport $port -j ACCEPT"
|
||||
exec { "access_to_nailgun_${protocol}_port: $port":
|
||||
command => "iptables -t filter -I INPUT 1 $rule; \
|
||||
/etc/init.d/iptables save",
|
||||
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\""
|
||||
}
|
||||
}
|
||||
|
||||
define ip_forward($network) {
|
||||
$rule = "-s $network ! -o docker0 -j MASQUERADE"
|
||||
exec { "ip_forward: $network":
|
||||
command => "iptables -t nat -I POSTROUTING 1 $rule; \
|
||||
/etc/init.d/iptables save",
|
||||
unless => "iptables -t nat -S POSTROUTING | grep -q \"^-A POSTROUTING $rule\""
|
||||
}
|
||||
sysctl::value{'net.ipv4.ip_forward': value=>'1'}
|
||||
}
|
||||
|
||||
access_to_nailgun_port { "nailgun_web": port => '8000' }
|
||||
access_to_nailgun_port { "nailgun_repo": port => '8080' }
|
||||
class nailgun::iptables (
|
||||
$production = 'docker',
|
||||
$admin_iface = 'eth0',
|
||||
$ssh_port = '22',
|
||||
$nailgun_web_port = '8000',
|
||||
$nailgun_internal_port = '8001',
|
||||
$nailgun_repo_port = '8080',
|
||||
$postgres_port = '5432',
|
||||
$ostf_port = '8777',
|
||||
$rsync_port = '873',
|
||||
$rsyslog_port = '514',
|
||||
$ntp_port = '123',
|
||||
$rabbitmq_ports = ['4369','5672','15672','61613'],
|
||||
$chain = 'INPUT',
|
||||
)
|
||||
{
|
||||
#Host services
|
||||
$network_address = ipcalc_network_by_address_netmask($::fuel_settings['ADMIN_NETWORK']['ipaddress'],$::fuel_settings['ADMIN_NETWORK']['netmask'])
|
||||
$network_cidr = ipcalc_network_cidr_by_netmask($::fuel_settings['ADMIN_NETWORK']['netmask'])
|
||||
ip_forward {'forward_slaves': network => "${network_address}/${network_cidr}"}
|
||||
firewall { '004 forward_admin_net':
|
||||
chain => 'POSTROUTING',
|
||||
table => 'nat',
|
||||
source => "${network_address}/${network_cidr}",
|
||||
outiface => 'eth+',
|
||||
jump => 'MASQUERADE',
|
||||
}
|
||||
sysctl::value{'net.ipv4.ip_forward': value=>'1'}
|
||||
|
||||
firewall { '005 ssh':
|
||||
port => $ssh_port,
|
||||
proto => 'tcp',
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '006 ntp':
|
||||
port => $ntp_port,
|
||||
proto => 'tcp',
|
||||
iniface => $admin_iface,
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '007 ntp_udp':
|
||||
port => $ntp_port,
|
||||
proto => 'udp',
|
||||
iniface => $admin_iface,
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '008 snmp':
|
||||
port => '162',
|
||||
proto => 'udp',
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
#Containerized services
|
||||
firewall { '009 nailgun_web':
|
||||
chain => $chain,
|
||||
port => $nailgun_web_port,
|
||||
proto => 'tcp',
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '010 nailgun_internal':
|
||||
chain => $chain,
|
||||
port => $nailgun_internal_port,
|
||||
proto => 'tcp',
|
||||
iniface => 'docker0',
|
||||
action => 'accept',
|
||||
}
|
||||
firewall { '011 nailgun_internal_local':
|
||||
chain => $chain,
|
||||
port => $nailgun_internal_port,
|
||||
proto => 'tcp',
|
||||
src_type => "LOCAL",
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '012 nailgun_internal_block_ext':
|
||||
chain => $chain,
|
||||
port => $nailgun_internal_port,
|
||||
proto => 'tcp',
|
||||
action => 'reject',
|
||||
}
|
||||
|
||||
firewall { '013 postgres_local':
|
||||
chain => $chain,
|
||||
port => $postgres_port,
|
||||
proto => 'tcp',
|
||||
src_type => "LOCAL",
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '014 postgres':
|
||||
chain => $chain,
|
||||
port => $postgres_port,
|
||||
proto => 'tcp',
|
||||
iniface => 'docker0',
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '015 postgres_block_ext':
|
||||
chain => $chain,
|
||||
port => $postgres_port,
|
||||
proto => 'tcp',
|
||||
action => 'reject',
|
||||
}
|
||||
|
||||
firewall { '020 ostf_admin':
|
||||
chain => $chain,
|
||||
port => $ostf_port,
|
||||
proto => 'tcp',
|
||||
iniface => $admin_iface,
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '021 ostf_local':
|
||||
chain => $chain,
|
||||
port => $ostf_port,
|
||||
proto => 'tcp',
|
||||
src_type => "LOCAL",
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '022 ostf_block_ext':
|
||||
chain => $chain,
|
||||
port => $ostf_port,
|
||||
proto => 'tcp',
|
||||
action => 'reject',
|
||||
}
|
||||
|
||||
firewall { '023 rsync':
|
||||
chain => $chain,
|
||||
port => $rsync_port,
|
||||
proto => 'tcp',
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '024 rsyslog':
|
||||
chain => $chain,
|
||||
port => $rsync_port,
|
||||
proto => 'tcp',
|
||||
iniface => $admin_iface,
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '040 rabbitmq_admin':
|
||||
chain => $chain,
|
||||
port => $rabbitmq_ports,
|
||||
proto => 'tcp',
|
||||
iniface => $admin_iface,
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '041 rabbitmq_local':
|
||||
chain => $chain,
|
||||
port => $rabbitmq_ports,
|
||||
proto => 'tcp',
|
||||
src_type => "LOCAL",
|
||||
action => 'accept',
|
||||
}
|
||||
|
||||
firewall { '042 rabbitmq_block_ext':
|
||||
chain => $chain,
|
||||
port => $rabbitmq_ports,
|
||||
proto => 'tcp',
|
||||
action => 'reject',
|
||||
}
|
||||
|
||||
firewall {'999 iptables denied':
|
||||
chain => 'INPUT',
|
||||
limit => '5/min',
|
||||
jump => 'LOG',
|
||||
log_prefix => 'iptables denied: ',
|
||||
log_level => '7',
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,17 +16,6 @@ class nailgun::rabbitmq (
|
||||
anchor { 'nailgun::rabbitmq start' :}
|
||||
anchor { 'nailgun::rabbitmq end' :}
|
||||
|
||||
define access_to_rabbitmq_port ($port, $protocol = 'tcp') {
|
||||
$rule = "-p $protocol -m state --state NEW -m $protocol --dport $port -j ACCEPT"
|
||||
|
||||
exec { "access_to_cobbler_${protocol}_port: $port":
|
||||
command => "iptables -t filter -I INPUT 1 $rule; \
|
||||
/etc/init.d/iptables save",
|
||||
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\"",
|
||||
path => '/bin:/usr/bin:/sbin:/usr/sbin',
|
||||
}
|
||||
}
|
||||
|
||||
if $production =~ /docker/ {
|
||||
#Known issue: ulimit is disabled inside docker containers
|
||||
file { '/etc/default/rabbitmq-server':
|
||||
@ -35,18 +24,6 @@ class nailgun::rabbitmq (
|
||||
before => Service['rabbitmq-server'],
|
||||
}
|
||||
}
|
||||
else {
|
||||
case $::osfamily {
|
||||
'Debian' : {
|
||||
}
|
||||
'RedHat' : {
|
||||
access_to_rabbitmq_port { "${stompport}_tcp": port => $stompport }
|
||||
}
|
||||
default : {
|
||||
fail("Unsupported osfamily: ${osfamily} for os ${operatingsystem}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rabbitmq_user { $astute_user:
|
||||
admin => true,
|
||||
|
Loading…
Reference in New Issue
Block a user