Initial refactoring
Renamed rhizomatica_base_system to rhizo_base Split up the init.pp in different subclasses More work to follow
This commit is contained in:
parent
7b938abede
commit
1c7dffc32a
192 changed files with 547 additions and 430 deletions
28
modules/rhizo_base/manifests/apt.pp
Normal file
28
modules/rhizo_base/manifests/apt.pp
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Class: rhizo_base::apt
|
||||
#
|
||||
# This module manages the apt repositories
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::apt {
|
||||
class { 'apt': }
|
||||
apt::ppa { 'ppa:keithw/mosh': }
|
||||
apt::ppa { 'ppa:ondrej/php5': }
|
||||
file { '/etc/apt/apt.conf.d/90unsigned':
|
||||
ensure => present,
|
||||
content => 'APT::Get::AllowUnauthenticated "true";',
|
||||
}
|
||||
apt::source { 'rhizomatica':
|
||||
location => 'http://dev.rhizomatica.org/ubuntu/',
|
||||
release => 'precise',
|
||||
repos => 'main',
|
||||
include_src => false,
|
||||
require => File['/etc/apt/apt.conf.d/90unsigned'],
|
||||
}
|
||||
}
|
31
modules/rhizo_base/manifests/fixes.pp
Normal file
31
modules/rhizo_base/manifests/fixes.pp
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Class: rhizo_base::fixes
|
||||
#
|
||||
# This module manages various system fixes
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::fixes {
|
||||
#FSCK at boot
|
||||
file { '/etc/default/rcS':
|
||||
ensure => present,
|
||||
source => 'puppet:///modules/rhizomatica_base_system/etc/default/rcS',
|
||||
}
|
||||
|
||||
#Grub fix
|
||||
file { '/etc/default/grub':
|
||||
ensure => present,
|
||||
source => 'puppet:///modules/rhizomatica_base_system/etc/default/grub',
|
||||
notify => Exec['update-grub'],
|
||||
}
|
||||
|
||||
exec { 'update-grub':
|
||||
command => '/usr/sbin/update-grub',
|
||||
refreshonly => true,
|
||||
}
|
||||
}
|
75
modules/rhizo_base/manifests/freeswitch.pp
Normal file
75
modules/rhizo_base/manifests/freeswitch.pp
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Class: rhizo_base::freeswitch
|
||||
#
|
||||
# This module manages the FreeSWITCH system
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::freeswitch {
|
||||
#FreeSWITCH
|
||||
package {
|
||||
['freeswitch', 'freeswitch-lang-en',
|
||||
'freeswitch-mod-amr', 'freeswitch-mod-amrwb',
|
||||
'freeswitch-mod-b64', 'freeswitch-mod-bv',
|
||||
'freeswitch-mod-cdr-pg-csv', 'freeswitch-mod-cluechoo',
|
||||
'freeswitch-mod-commands', 'freeswitch-mod-conference',
|
||||
'freeswitch-mod-console', 'freeswitch-mod-db',
|
||||
'freeswitch-mod-dialplan-asterisk', 'freeswitch-mod-dialplan-xml',
|
||||
'freeswitch-mod-dptools', 'freeswitch-mod-enum',
|
||||
'freeswitch-mod-esf', 'freeswitch-mod-event-socket',
|
||||
'freeswitch-mod-expr', 'freeswitch-mod-fifo',
|
||||
'freeswitch-mod-fsv', 'freeswitch-mod-g723-1',
|
||||
'freeswitch-mod-h26x', 'freeswitch-mod-hash',
|
||||
'freeswitch-mod-httapi', 'freeswitch-mod-local-stream',
|
||||
'freeswitch-mod-logfile', 'freeswitch-mod-loopback',
|
||||
'freeswitch-mod-lua', 'freeswitch-mod-native-file',
|
||||
'freeswitch-mod-python', 'freeswitch-mod-say-en',
|
||||
'freeswitch-mod-say-es', 'freeswitch-mod-sms',
|
||||
'freeswitch-mod-sndfile', 'freeswitch-mod-sofia',
|
||||
'freeswitch-mod-spandsp', 'freeswitch-mod-speex',
|
||||
'freeswitch-mod-syslog', 'freeswitch-mod-tone-stream',
|
||||
'freeswitch-mod-voicemail', 'freeswitch-mod-voicemail-ivr',
|
||||
'freeswitch-mod-vp8', 'freeswitch-mod-xml-cdr',
|
||||
'freeswitch-sysvinit', 'libfreeswitch1']:
|
||||
ensure => installed,
|
||||
require => Class['rhizo_base::apt'],
|
||||
}
|
||||
|
||||
file { '/usr/lib/freeswitch/mod/mod_g729.so':
|
||||
source => 'puppet:///modules/rhizo_base/mod_g729.so',
|
||||
require => Package['freeswitch'],
|
||||
}
|
||||
|
||||
file { '/etc/freeswitch':
|
||||
ensure => directory,
|
||||
source => 'puppet:///modules/rhizo_base/etc/freeswitch',
|
||||
recurse => remote,
|
||||
require => Package['freeswitch'],
|
||||
}
|
||||
|
||||
file { '/etc/freeswitch/vars.xml':
|
||||
content => template('rhizo_base/vars.xml.erb'),
|
||||
require => Package['freeswitch'],
|
||||
}
|
||||
|
||||
file {'/etc/freeswitch/sip_profiles/external':
|
||||
ensure => directory,
|
||||
}
|
||||
|
||||
file { '/etc/freeswitch/sip_profiles/external/provider.xml':
|
||||
content => template('rhizo_base/provider.xml.erb'),
|
||||
require =>
|
||||
[ Package['freeswitch'],
|
||||
File['/etc/freeswitch/sip_profiles/external'] ],
|
||||
}
|
||||
|
||||
file { '/etc/freeswitch/autoload_configs/cdr_pg_csv.conf.xml':
|
||||
content => template('rhizo_base/cdr_pg_csv.conf.xml.erb'),
|
||||
require => Package['freeswitch'],
|
||||
}
|
||||
}
|
242
modules/rhizo_base/manifests/init.pp
Normal file
242
modules/rhizo_base/manifests/init.pp
Normal file
|
@ -0,0 +1,242 @@
|
|||
# Class: rhizo_base
|
||||
#
|
||||
# This module manages the Rhizomatica base system
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base {
|
||||
|
||||
$mail_admins = hiera('rhizo::mail_admins')
|
||||
$smsc_password = hiera('rhizo::smsc_password')
|
||||
$kannel_admin_password = hiera('rhizo::kannel_admin_password')
|
||||
|
||||
# Configuration settings
|
||||
$rhizomatica_dir = hiera('rhizo::rhizomatica_dir')
|
||||
$sq_hlr_path = hiera('rhizo::sq_hlr_path')
|
||||
|
||||
# database
|
||||
$pgsql_db = hiera('rhizo::pgsql_db')
|
||||
$pgsql_user = hiera('rhizo::pgsql_user')
|
||||
$pgsql_pwd = hiera('rhizo::pgsql_pwd')
|
||||
$pgsql_host = hiera('rhizo::pgsql_host')
|
||||
|
||||
# SITE
|
||||
$site_name = hiera('rhizo::site_name')
|
||||
$postcode = hiera('rhizo::postcode')
|
||||
$pbxcode = hiera('rhizo::pbxcode')
|
||||
# network name
|
||||
$network_name = hiera('rhizo::network_name')
|
||||
$auth_policy = hiera('rhizo::auth_policy')
|
||||
|
||||
#BTSs configuration
|
||||
$bts1_ip_address = hiera('rhizo::bts1_ip_address')
|
||||
$arfcn_A = hiera('rhizo::arfcn_A')
|
||||
$arfcn_B = hiera('rhizo::arfcn_B')
|
||||
|
||||
$bts2_ip_address = hiera('rhizo::bts2_ip_address', false)
|
||||
$arfcn_C = hiera('rhizo::arfcn_C', false)
|
||||
$arfcn_D = hiera('rhizo::arfcn_D', false)
|
||||
|
||||
$bts3_ip_address = hiera('rhizo::bts3_ip_address', false)
|
||||
$arfcn_E = hiera('rhizo::arfcn_E', false)
|
||||
$arfcn_F = hiera('rhizo::arfcn_F', false)
|
||||
|
||||
$max_power_red = hiera('rhizo::max_power_red')
|
||||
|
||||
# VPN ip address
|
||||
$vpn_ip_address = hiera('rhizo::vpn_ip_address')
|
||||
$wan_ip_address = hiera('rhizo::wan_ip_address')
|
||||
|
||||
# SITE settings
|
||||
# rate type can be "call" or "min"
|
||||
$limit_local_calls = hiera('rhizo::limit_local_calls')
|
||||
$limit_local_minutes = hiera('rhizo::limit_local_minutes')
|
||||
$charge_local_calls = hiera('rhizo::charge_local_calls')
|
||||
$charge_local_rate = hiera('rhizo::charge_local_rate')
|
||||
$charge_local_rate_type = hiera('rhizo::charge_local_rate_type')
|
||||
$charge_internal_calls = hiera('rhizo::charge_internal_calls')
|
||||
$charge_internal_rate = hiera('rhizo::charge_internal_rate')
|
||||
$charge_internal_rate_type = hiera('rhizo::charge_internal_rate_type')
|
||||
$charge_inbound_calls = hiera('rhizo::charge_inbound_calls')
|
||||
$charge_inbound_rate = hiera('rhizo::charge_inbound_rate')
|
||||
$charge_inbound_rate_type = hiera('rhizo::charge_inbound_rate_type')
|
||||
$smsc_shortcode = hiera('rhizo::smsc_shortcode')
|
||||
$sms_sender_unauthorized = hiera('rhizo::sms_sender_unauthorized')
|
||||
$sms_destination_unauthorized = hiera('rhizo::sms_destination_unauthorized')
|
||||
|
||||
$rai_admin_user = hiera('rhizo::rai_admin_user')
|
||||
$rai_admin_pwd = hiera('rhizo::rai_admin_pwd')
|
||||
|
||||
$kannel_server = hiera('rhizo::kannel_server')
|
||||
$kannel_port = hiera('rhizo::kannel_port')
|
||||
$kannel_username = hiera('rhizo::kannel_username')
|
||||
$kannel_sendsms_password = hiera('rhizo::kannel_sendsms_password')
|
||||
|
||||
# VOIP provider
|
||||
$voip_provider_name = hiera('rhizo::voip_provider_name')
|
||||
$voip_username = hiera('rhizo::voip_username')
|
||||
$voip_fromuser = hiera('rhizo::voip_fromuser')
|
||||
$voip_password = hiera('rhizo::voip_password')
|
||||
$voip_proxy = hiera('rhizo::voip_proxy')
|
||||
$voip_did = hiera('rhizo::voip_did')
|
||||
$voip_cli = hiera('rhizo::voip_cli')
|
||||
|
||||
# Subscription SMS notification
|
||||
$notice_msg = hiera('rhizo::notice_msg')
|
||||
$reminder_msg = hiera('rhizo::reminder_msg')
|
||||
$deactivate_msg = hiera('rhizo::deactivate_msg')
|
||||
$sms_credit_added = hiera('rhizo::sms_credit_added')
|
||||
|
||||
#Roaming welcome SMS
|
||||
$sms_welcome_roaming = hiera('rhizo::sms_welcome_roaming')
|
||||
#Emergency number
|
||||
$emergency_contact = hiera('rhizo::emergency_contact')
|
||||
|
||||
include ntp
|
||||
include kannel
|
||||
include rhizo_base::fixes
|
||||
include rhizo_base::apt
|
||||
include rhizo_base::postgresql
|
||||
include rhizo_base::riak
|
||||
include rhizo_base::packages
|
||||
include rhizo_base::freeswitch
|
||||
include rhizo_base::runit
|
||||
include rhizo_base::openbsc
|
||||
include rhizo_base::lcr
|
||||
|
||||
#Rizhomatica scripts
|
||||
file { '/home/rhizomatica/bin':
|
||||
ensure => directory,
|
||||
source => 'puppet:///modules/rhizo_base/bin',
|
||||
recurse => true,
|
||||
purge => false,
|
||||
}
|
||||
|
||||
file { '/home/rhizomatica/bin/vars.sh':
|
||||
ensure => present,
|
||||
content => template('rhizo_base/vars.sh.erb'),
|
||||
}
|
||||
|
||||
file { '/var/rhizomatica':
|
||||
ensure => directory,
|
||||
}
|
||||
|
||||
file { '/var/rhizo_backups':
|
||||
ensure => directory,
|
||||
}
|
||||
|
||||
file { '/var/rhizo_backups/postgresql':
|
||||
ensure => directory,
|
||||
owner => 'postgres',
|
||||
group => 'postgres',
|
||||
require => File['/var/rhizo_backups'],
|
||||
}
|
||||
|
||||
file { '/var/rhizo_backups/sqlite':
|
||||
ensure => directory,
|
||||
require => File['/var/rhizo_backups'],
|
||||
}
|
||||
|
||||
# vcsrepo { '/var/rhizomatica':
|
||||
# ensure => latest,
|
||||
# provider => git,
|
||||
# source => 'https://github.com/Rhizomatica/rccn.git',
|
||||
# revision => 'master',
|
||||
# require => [ File['/var/rhizomatica'], Package['git'] ],
|
||||
# notify => [ Exec['install_rccn'], Exec['locale-gen'] ],
|
||||
# }
|
||||
|
||||
file { '/var/rhizomatica/rccn/config_values.py':
|
||||
ensure => present,
|
||||
content => template('rhizo_base/config_values.py.erb'),
|
||||
# require => Vcsrepo['/var/rhizomatica'],
|
||||
}
|
||||
|
||||
file { '/var/rhizomatica/rai/include/database.php':
|
||||
ensure => present,
|
||||
content => template('rhizo_base/database.php.erb'),
|
||||
# require => Vcsrepo['/var/rhizomatica'],
|
||||
}
|
||||
|
||||
exec { 'install_rccn':
|
||||
command => '/usr/bin/python /var/rhizomatica/rccn/install.py',
|
||||
require => [ File['/var/rhizomatica/rccn/config_values.py'],
|
||||
Class['rhizo_base::postgresql'], Class['riak'],
|
||||
Package['php5'] ],
|
||||
refreshonly => true,
|
||||
}
|
||||
|
||||
exec { 'locale-gen':
|
||||
command => '/usr/sbin/locale-gen',
|
||||
require => [ File['/var/rhizomatica/rccn/config_values.py'],
|
||||
File['/var/lib/locales/supported.d/local'] ],
|
||||
refreshonly => true,
|
||||
}
|
||||
|
||||
file { '/var/lib/locales/supported.d/local':
|
||||
ensure => present,
|
||||
source => 'puppet:///modules/rhizo_base/var/lib/locales/supported.d/local',
|
||||
}
|
||||
|
||||
file { '/var/www/html/rai':
|
||||
ensure => link,
|
||||
target => '/var/rhizomatica/rai',
|
||||
require => Package['apache2'],
|
||||
# [ Vcsrepo['/var/rhizomatica'], ],
|
||||
}
|
||||
|
||||
file { '/var/www/html/rai/graphs':
|
||||
ensure => link,
|
||||
target => '/var/rhizomatica/rrd/graphs',
|
||||
# require => Vcsrepo['/var/rhizomatica'],
|
||||
}
|
||||
|
||||
|
||||
#Python modules
|
||||
class { 'python':
|
||||
version => 'system',
|
||||
pip => true,
|
||||
dev => true,
|
||||
}
|
||||
|
||||
python::pip { 'riak':
|
||||
ensure => '2.0.3',
|
||||
pkgname => 'riak',
|
||||
}
|
||||
|
||||
file { '/usr/lib/python2.7/dist-packages':
|
||||
ensure => directory,
|
||||
source => 'puppet:///modules/rhizo_base/usr/lib/python2.7/dist-packages',
|
||||
recurse => remote,
|
||||
require => Class['python'],
|
||||
}
|
||||
|
||||
#Apache2 + PHP + Python
|
||||
package { ['apache2','libapache2-mod-php5',
|
||||
'rrdtool', 'python-twisted-web', 'python-psycopg2',
|
||||
'python-pysqlite2', 'php5', 'php5-pgsql',
|
||||
'php5-curl', 'php5-cli', 'php5-gd', 'python-corepost',
|
||||
'python-yaml', 'python-formencode', 'python-unidecode',
|
||||
'python-dateutil']:
|
||||
ensure => installed,
|
||||
require => Class['rhizo_base::apt'],
|
||||
}
|
||||
|
||||
file { '/etc/php5/apache2/php.ini':
|
||||
ensure => present,
|
||||
source => 'puppet:///modules/rhizo_base/etc/php5/apache2/php.ini',
|
||||
require => Package['libapache2-mod-php5'],
|
||||
}
|
||||
|
||||
|
||||
file { '/etc/cron.d/rhizomatica':
|
||||
source => 'puppet:///modules/rhizo_base/etc/cron.d/rhizomatica',
|
||||
}
|
||||
|
||||
}
|
33
modules/rhizo_base/manifests/lcr.pp
Normal file
33
modules/rhizo_base/manifests/lcr.pp
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Class: rhizo_base::lcr
|
||||
#
|
||||
# This module manages the LCR system
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::lcr {
|
||||
package { 'lcr':
|
||||
ensure => installed,
|
||||
require => Class['rhizo_base::apt'],
|
||||
}
|
||||
|
||||
file { '/usr/etc/lcr':
|
||||
ensure => directory,
|
||||
source => 'puppet:///modules/rhizo_base/usr/etc/lcr',
|
||||
recurse => remote,
|
||||
purge => true,
|
||||
require => Package['lcr'],
|
||||
}
|
||||
|
||||
file { '/etc/default/lcr':
|
||||
ensure => present,
|
||||
source => 'puppet:///modules/rhizo_base/etc/default/lcr',
|
||||
require => Package['lcr'],
|
||||
}
|
||||
|
||||
}
|
32
modules/rhizo_base/manifests/openbsc.pp
Normal file
32
modules/rhizo_base/manifests/openbsc.pp
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Class: rhizo_base::openbsc
|
||||
#
|
||||
# This module manages the OpenBSC system
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::openbsc {
|
||||
package { ['osmocom-nitb', 'osmocom-nitb-dbg',
|
||||
'libdbd-sqlite3', 'libsmpp0']:
|
||||
ensure => installed,
|
||||
require => Class['rhizo_base::apt'],
|
||||
notify => Exec['hlr_pragma_wal'],
|
||||
}
|
||||
|
||||
file { '/etc/osmocom/osmo-nitb.cfg':
|
||||
content => template('rhizo_base/osmo-nitb.cfg.erb'),
|
||||
require => Package['osmocom-nitb'],
|
||||
}
|
||||
|
||||
exec { 'hlr_pragma_wal':
|
||||
command =>
|
||||
'/usr/bin/sqlite3 /var/lib/osmocom/hlr.sqlite3 "PRAGMA journal_mode=wal;"',
|
||||
require => Class['rhizo_base::packages'],
|
||||
refreshonly => true,
|
||||
}
|
||||
}
|
21
modules/rhizo_base/manifests/packages.pp
Normal file
21
modules/rhizo_base/manifests/packages.pp
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Class: rhizo_base
|
||||
#
|
||||
# This module manages the packages not included in other modules
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::packages {
|
||||
|
||||
package { ['mosh', 'git', 'openvpn', 'lm-sensors', 'runit', 'sqlite3',
|
||||
'libffi-dev']:
|
||||
ensure => installed,
|
||||
require => Class['rhizo_base::apt'],
|
||||
}
|
||||
|
||||
}
|
25
modules/rhizo_base/manifests/postgresql.pp
Normal file
25
modules/rhizo_base/manifests/postgresql.pp
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Class: rhizo_base::postgresql
|
||||
#
|
||||
# This module manages the PostgreSQL database
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::postgresql {
|
||||
class { 'postgresql::globals':
|
||||
manage_package_repo => true,
|
||||
version => '9.3',
|
||||
}->
|
||||
class { 'postgresql::server':
|
||||
}
|
||||
|
||||
postgresql::server::db { 'rhizomatica':
|
||||
user => 'rhizomatica',
|
||||
password => postgresql_password('rhizomatica', $pgsql_pwd),
|
||||
}
|
||||
}
|
19
modules/rhizo_base/manifests/riak.pp
Normal file
19
modules/rhizo_base/manifests/riak.pp
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Class: rhizo_base::riak
|
||||
#
|
||||
# This module manages the Riak database
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::riak {
|
||||
class { 'riak':
|
||||
version => '1.4.10-1',
|
||||
template => 'rhizo_base/app.config.erb',
|
||||
vmargs_template => 'rhizo_base/vm.args.erb',
|
||||
}
|
||||
}
|
41
modules/rhizo_base/manifests/runit.pp
Normal file
41
modules/rhizo_base/manifests/runit.pp
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Class: rhizo_base::runit
|
||||
#
|
||||
# This module manages the Runit startup scripts
|
||||
#
|
||||
# Parameters: none
|
||||
#
|
||||
# Actions:
|
||||
#
|
||||
# Requires: see Modulefile
|
||||
#
|
||||
# Sample Usage:
|
||||
#
|
||||
class rhizo_base::runit {
|
||||
file { '/etc/sv':
|
||||
ensure => directory,
|
||||
source => 'puppet:///modules/rhizo_base/etc/sv',
|
||||
recurse => remote,
|
||||
require => Class['rhizo_base::packages'],
|
||||
}
|
||||
|
||||
file { '/etc/service/osmo-nitb':
|
||||
ensure => link,
|
||||
target => '/etc/sv/osmo-nitb',
|
||||
require =>
|
||||
[ File['/etc/sv'], Class['rhizo_base::openbsc'] ],
|
||||
}
|
||||
|
||||
file { '/etc/service/freeswitch':
|
||||
ensure => link,
|
||||
target => '/etc/sv/freeswitch',
|
||||
require =>
|
||||
[ File['/etc/sv'], Class['rhizo_base::freeswitch'] ],
|
||||
}
|
||||
|
||||
file { '/etc/service/rapi':
|
||||
ensure => link,
|
||||
target => '/etc/sv/rapi',
|
||||
require => File['/etc/sv'],
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue