diff --git a/.gitignore b/.gitignore
index d513b9e..afb6b4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.*.swp
__pycache__
+files/ssh/backup.pub
diff --git a/container-ports.md b/container-ports.md
new file mode 100644
index 0000000..25fcc97
--- /dev/null
+++ b/container-ports.md
@@ -0,0 +1,16 @@
+# Ports used by container web services
+
+| Port | Ansible role | Service name |
+|------|---------------------|----------------------------|
+| 8001 | kerberos_kdc | Kerberos KDC |
+| 8002 | grafana | Grafana |
+| 8003 | authcheck | Authentication check |
+| 8004 | roundcube | Roundcube webmail |
+| 8005 | php4dvd | php4dvd movie catalog |
+| 8006 | scanservjs | SANE Scanner webui |
+| 8007 | frigate | Network video recorder |
+| 8008 | hoemeassistant | Home Assistant |
+| 8009 | rocketchat | Rocket.Chat |
+| 8010 | google-spell-pspell | Google Spell Check XML API |
+| 8011 | ipsilon | Ipsilon Identity Provider |
+| 8012 | nodered | Node Red |
diff --git a/files/ssh/backup.pub b/files/ssh/backup.pub
deleted file mode 100644
index 336fbc7..0000000
--- a/files/ssh/backup.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKdaNO9dLpI8CVx1rwGsKN45Pgiz+Btrlf2Q/nXCx4Ru root@backup02.home.foo.sh
diff --git a/group_vars/adm.yml b/group_vars/adm.yml
index 0eff70a..a06d51b 100644
--- a/group_vars/adm.yml
+++ b/group_vars/adm.yml
@@ -1,8 +1,12 @@
---
datadisks:
- - {size: 10}
+ - {size: 10, type: nvme}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 80, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
+
+sssd_allow_groups:
+ - sysadm
diff --git a/group_vars/all.yml b/group_vars/all.yml
index 39ac197..13c4354 100644
--- a/group_vars/all.yml
+++ b/group_vars/all.yml
@@ -31,8 +31,10 @@ boot_url: https://boot.foo.sh
# ssh public keys for logsync user
logsync_publickeys: "{{ lookup('file', '../files/ssh/logsync.pub') }}"
-# ssh public keys for backup user
-backup_publickeys: "{{ lookup('file', '../files/ssh/backup.pub') }}"
+# default name servers
+network_dns_servers:
+ - 8.8.8.8
+ - 8.8.4.4
# hardcode this for now
ansible_datacenter: home
diff --git a/group_vars/gitea.yml b/group_vars/audiobooks.yml
similarity index 62%
rename from group_vars/gitea.yml
rename to group_vars/audiobooks.yml
index 985e033..4fcc30e 100644
--- a/group_vars/gitea.yml
+++ b/group_vars/audiobooks.yml
@@ -1,8 +1,8 @@
---
datadisks:
- - {size: 10, type: hdd}
+ - {size: 50, type: hdd}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/backup.yml b/group_vars/backup.yml
index ec4ea73..0b7f509 100644
--- a/group_vars/backup.yml
+++ b/group_vars/backup.yml
@@ -1,3 +1,4 @@
---
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/collab.yml b/group_vars/collab.yml
index a49673c..e80e98c 100644
--- a/group_vars/collab.yml
+++ b/group_vars/collab.yml
@@ -5,4 +5,4 @@ datadisks:
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/dnagw.yml b/group_vars/dnagw.yml
index 9b2bacc..fe380e8 100644
--- a/group_vars/dnagw.yml
+++ b/group_vars/dnagw.yml
@@ -12,12 +12,32 @@ network_vip_interfaces:
netmask: 255.255.252.0
pass: "{{ vip10_pass }}"
priority: 120
+ - device: vio0
+ vhid: 11
+ ipaddr: 172.20.20.11
+ netmask: 255.255.252.0
+ pass: "{{ vip11_pass }}"
+ priority: "{{ vip11_priority }}"
+ - device: vio0
+ vhid: 12
+ ipaddr: 172.20.20.12
+ netmask: 255.255.252.0
+ pass: "{{ vip12_pass }}"
+ priority: "{{ vip12_priority }}"
network_ether_interfaces:
- device: vio1
proto: none
+unbound_zones:
+ - 20.172.in-addr.arpa
+ - home.foo.sh
+
# use custom firewall config
firewall_src: pf.conf.gw_home
# ifstated config
ifstated_config: ifstated-dna.conf.j2
+
+# ssh host alaises
+ssh_hostnames:
+ - gw.home.foo.sh
diff --git a/group_vars/fedora.yml b/group_vars/fedora.yml
index c0ed1a5..1f7eeea 100644
--- a/group_vars/fedora.yml
+++ b/group_vars/fedora.yml
@@ -1,7 +1,7 @@
---
# default resources for new vm
dsk_size: 20
-mem_size: 2048
+mem_size: 4096
num_cpus: 2
# extra args for virt-install
@@ -18,7 +18,7 @@ ipcmd: >-
{% endif %}
virt_install_os_args: >-
--location
- https://nic.funet.fi/pub/mirrors/fedora.redhat.com/pub/fedora/linux/releases/38/Everything/x86_64/os/
+ https://nic.funet.fi/pub/mirrors/fedora.redhat.com/pub/fedora/linux/releases/41/Everything/x86_64/os/
--extra-args
"inst.ks={{ ks_file }}
console=ttyS0
diff --git a/group_vars/forgejo.yml b/group_vars/forgejo.yml
new file mode 100644
index 0000000..e80e98c
--- /dev/null
+++ b/group_vars/forgejo.yml
@@ -0,0 +1,8 @@
+---
+datadisks:
+ - {size: 10, type: nvme}
+
+firewall_in:
+ - {proto: tcp, port: 22, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 443, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/zm.yml b/group_vars/frigate.yml
similarity index 51%
rename from group_vars/zm.yml
rename to group_vars/frigate.yml
index 4da1f4f..81a93e1 100644
--- a/group_vars/zm.yml
+++ b/group_vars/frigate.yml
@@ -1,8 +1,9 @@
---
-mem_size: 4096
+mem_size: 8192
num_cpus: 2
datadisks:
- - {size: 500}
+ - {size: 50, type: nvme}
+ - {size: 500, type: hdd}
network_vip_interfaces:
- device: eth1
@@ -11,13 +12,16 @@ network_vip_interfaces:
netmask: 255.255.0.0
pass: "{{ vip26_pass }}"
-zm_mysql_host: sqldb02.home.foo.sh
+unbound_zones:
+ - 26.20.172.in-addr.arpa
+ - cam.foo.sh
dhcpd_template: dhcpd.conf.cam.j2
+dhcpd_ldap_filter: >-
+ (&(objectClass=ieee802Device)(objectClass=ipHost)(cn=*.cam.foo.sh))
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
firewall_raw:
- - "-A INPUT -i eth1 -d 224.0.0.0/8 -j ACCEPT"
- - "-A INPUT -i eth1 -p vrrp -j ACCEPT"
+ - "ip daddr 224.0.0.0/8 accept"
diff --git a/group_vars/fsolgw.yml b/group_vars/fsolgw.yml
index fc3b312..6012a52 100644
--- a/group_vars/fsolgw.yml
+++ b/group_vars/fsolgw.yml
@@ -4,8 +4,9 @@ network_vip_interfaces:
vhid: 145
ipaddr: 37.16.96.145
netmask: 255.255.255.240
+ ip6addr: 2a00:4cc1:6:1006::1
+ ip6netmask: 64
pass: "{{ vip145_pass }}"
-network_dns_servers: [172.20.20.10, 172.20.21.1, 172.20.21.2]
# use custom firewall and ifstated config
firewall_src: pf.conf.gw_fsol
diff --git a/group_vars/gitearunner.yml b/group_vars/gitearunner.yml
deleted file mode 100644
index c611eea..0000000
--- a/group_vars/gitearunner.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-firewall_in:
- - {proto: tcp, port: 22, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
diff --git a/group_vars/home.yml b/group_vars/home.yml
new file mode 100644
index 0000000..d8558c0
--- /dev/null
+++ b/group_vars/home.yml
@@ -0,0 +1,5 @@
+---
+network_dns_servers:
+ - 172.20.20.10
+ - 172.20.20.11
+ - 172.20.20.12
diff --git a/group_vars/homeassistant.yml b/group_vars/homeassistant.yml
index 91f88e0..d344ed1 100644
--- a/group_vars/homeassistant.yml
+++ b/group_vars/homeassistant.yml
@@ -1,7 +1,7 @@
---
datadisks:
- - {size: 10, type: hdd}
+ - {size: 10, type: nvme}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/influxdb.yml b/group_vars/influxdb.yml
index fcdcc1b..be5bea6 100644
--- a/group_vars/influxdb.yml
+++ b/group_vars/influxdb.yml
@@ -5,4 +5,4 @@ datadisks:
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/ldap.yml b/group_vars/ldap.yml
index 660bcb5..1e3e573 100644
--- a/group_vars/ldap.yml
+++ b/group_vars/ldap.yml
@@ -3,6 +3,5 @@ saslauthd_mech: ldap
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- - {proto: tcp, port: 443, from: [172.20.20.0/22]}
- {proto: tcp, port: 636, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/log.yml b/group_vars/log.yml
index 7457482..f7c44ba 100644
--- a/group_vars/log.yml
+++ b/group_vars/log.yml
@@ -1,8 +1,9 @@
---
+mem_size: 512
datadisks:
- - {size: 50}
+ - {size: 50, type: nvme}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
- {proto: tcp, port: 6514}
diff --git a/group_vars/mail.yml b/group_vars/mail.yml
index 7976023..4de52d0 100644
--- a/group_vars/mail.yml
+++ b/group_vars/mail.yml
@@ -1,6 +1,7 @@
---
datadisks:
- - {size: 10}
+ - {size: 10, type: nvme}
+mem_size: 4192
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
@@ -10,4 +11,7 @@ firewall_in:
- {proto: tcp, port: 465}
- {proto: tcp, port: 587}
- {proto: tcp, port: 993}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
+
+sssd_allow_groups:
+ - sysadm
diff --git a/group_vars/minecraft.yml b/group_vars/minecraft.yml
index cf60405..a7ff2b1 100644
--- a/group_vars/minecraft.yml
+++ b/group_vars/minecraft.yml
@@ -1,9 +1,9 @@
---
mem_size: 4096
datadisks:
- - {size: 100}
+ - {size: 100, type: nvme}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.30.0/24]}
+ - {proto: tcp, port: 9100, from: [172.20.30.0/24]}
- {proto: tcp, port: 25565, from: [172.20.30.0/24]}
- {proto: udp, port: 25565, from: [172.20.30.0/24]}
diff --git a/group_vars/mirror.yml b/group_vars/mirror.yml
index 4ac63b1..c21d751 100644
--- a/group_vars/mirror.yml
+++ b/group_vars/mirror.yml
@@ -1,10 +1,9 @@
---
-
datadisks:
- - {size: 1000}
+ - {size: 1500, type: hdd}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- {proto: tcp, port: 873, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/mongodb.yml b/group_vars/mongodb.yml
index e17dd45..656811d 100644
--- a/group_vars/mongodb.yml
+++ b/group_vars/mongodb.yml
@@ -4,3 +4,4 @@ datadisks:
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 27017, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/mqtt.yml b/group_vars/mqtt.yml
index ec10fe7..e64ff98 100644
--- a/group_vars/mqtt.yml
+++ b/group_vars/mqtt.yml
@@ -3,5 +3,5 @@ firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.27.0/24]}
- {proto: tcp, port: 1883, from: [172.20.27.0/24]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
- {proto: tcp, port: 8883, from: [172.20.20.0/22, 172.20.27.0/24]}
diff --git a/group_vars/nas.yml b/group_vars/nas.yml
index 84be798..5dac726 100644
--- a/group_vars/nas.yml
+++ b/group_vars/nas.yml
@@ -2,11 +2,14 @@
mem_size: 8192
num_cpus: 2
datadisks:
- - {size: 1000}
- - {size: 400, type: nvme}
+ - {size: 500, type: nvme}
+ - {size: 50, type: nvme}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 2049, from: [172.20.20.0/22]}
- {proto: tcp, port: 2049, from: [172.20.30.0/24]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
+
+sssd_allow_groups:
+ - root
diff --git a/group_vars/nms.yml b/group_vars/nms.yml
index 83c016a..bd86e46 100644
--- a/group_vars/nms.yml
+++ b/group_vars/nms.yml
@@ -1,12 +1,24 @@
---
datadisks:
- - {size: 10}
+ - {size: 10, type: nvme}
+
+unbound_zones:
+ - 25.20.172.in-addr.arpa
+ - oob.foo.sh
+dhcpd_template: dhcpd.conf.oob.j2
+dhcpd_ldap_filter: >-
+ (&(objectClass=ieee802Device)(objectClass=ipHost)(cn=*.oob.foo.sh))
network_vip_interfaces:
+ - device: eth0
+ vhid: 11
+ ipaddr: 172.20.20.21
+ netmask: 255.255.240.0
+ pass: "{{ vip21_pass }}"
- device: eth1
vhid: 25
ipaddr: 172.20.25.1
- netmask: 255.255.0.0
+ netmask: 255.255.255.0
pass: "{{ vip25_pass }}"
priority: "{{ vip25_priority }}"
@@ -19,7 +31,10 @@ firewall_in:
- {proto: udp, port: 123, from: [172.20.25.0/24]}
- {proto: tcp, port: 443, from: [172.20.25.0/24]}
- {proto: udp, port: 514, from: [172.20.25.0/24]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9116, from: [172.20.20.0/22]}
firewall_raw:
- - "-A INPUT -i eth1 -d 224.0.0.0/8 -j ACCEPT"
- - "-A INPUT -i eth1 -p vrrp -j ACCEPT"
+ - "ip daddr 224.0.0.0/8 accept"
+
+sssd_allow_groups:
+ - sysadm
diff --git a/group_vars/ns.yml b/group_vars/ns.yml
index 6542553..2a284b1 100644
--- a/group_vars/ns.yml
+++ b/group_vars/ns.yml
@@ -1,12 +1,13 @@
---
firewall_in:
- - {proto: tcp, port: 22, from: [172.20.20.0/22, 81.175.130.44/32]}
+ - {proto: tcp, port: 22, from: [172.20.20.0/22, 212.149.225.204/32]}
- {proto: tcp, port: 53}
- {proto: udp, port: 53}
- {proto: tcp, port: 80}
- {proto: tcp, port: 443}
- {proto: tcp, port: 853}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22, 81.175.130.44/32]}
+ - {proto: tcp, port: 9100}
+ - {proto: tcp, port: 9115}
firewall_raw:
- pass quick proto carp
diff --git a/group_vars/ocinode.yml b/group_vars/ocinode.yml
index 9945015..d66dfb6 100644
--- a/group_vars/ocinode.yml
+++ b/group_vars/ocinode.yml
@@ -1,7 +1,10 @@
---
# increase memory size
-mem_size: 4192
+mem_size: 8192
+# increase disk size to store docker images
+dsk_size: 100
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/openbsd.yml b/group_vars/openbsd.yml
index 51337c9..2695e29 100644
--- a/group_vars/openbsd.yml
+++ b/group_vars/openbsd.yml
@@ -17,5 +17,5 @@ num_cpus: 2
# extra args for virt-install
virt_install_os_args: --cdrom {{ boot_url }}/openbsd/openbsd.iso
-virt_install_os_variant: openbsd7.0
-virt_install_python_cmd: pkg_add python3 -I -x
+virt_install_os_variant: openbsd7.4
+virt_install_python_cmd: pkg_add -I -x python
diff --git a/group_vars/print.yml b/group_vars/print.yml
index 7029178..fc2e3fb 100644
--- a/group_vars/print.yml
+++ b/group_vars/print.yml
@@ -7,14 +7,20 @@ network_vip_interfaces:
pass: "{{ vip24_pass }}"
priority: "{{ vip24_priority }}"
-dhcpd_template: dhcpd.conf.print.j2
-
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 53, from: [172.20.24.0/24]}
- {proto: udp, port: 53, from: [172.20.24.0/24]}
- {proto: tcp, port: 631, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
firewall_raw:
- - "-A INPUT -i eth1 -d 224.0.0.0/8 -j ACCEPT"
- - "-A INPUT -i eth1 -p vrrp -j ACCEPT"
+ - "ip daddr 224.0.0.0/8 accept"
+
+dhcpd_template: dhcpd.conf.print.j2
+dhcpd_ldap_filter: >-
+ (&(objectClass=ieee802Device)(objectClass=ipHost)(cn=*.print.foo.sh))
+sssd_allow_groups:
+ - sysadm
+unbound_zones:
+ - 24.20.172.in-addr.arpa
+ - print.foo.sh
diff --git a/group_vars/prometheus.yml b/group_vars/prometheus.yml
new file mode 100644
index 0000000..be5bea6
--- /dev/null
+++ b/group_vars/prometheus.yml
@@ -0,0 +1,8 @@
+---
+datadisks:
+ - {size: 100, type: nvme}
+
+firewall_in:
+ - {proto: tcp, port: 22, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 443, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/proxy.yml b/group_vars/proxy.yml
index c3ffdcd..ea7cba9 100644
--- a/group_vars/proxy.yml
+++ b/group_vars/proxy.yml
@@ -4,12 +4,6 @@ mem_size: 1024
# use bigger disk for os as we have web site data there
dsk_size: 30
-network_dns_servers:
- - 172.20.20.10
- - 172.20.21.7
- - 172.20.21.8
-network_dns_search:
- - foo.sh
network_default_gateway: 37.16.96.145
network_vip_interfaces:
@@ -48,6 +42,4 @@ firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 80}
- {proto: tcp, port: 443}
- - {proto: tcp, port: 636}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
- - {proto: tcp, port: 6514}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/relay.yml b/group_vars/relay.yml
index b48a3a2..a52f0b5 100644
--- a/group_vars/relay.yml
+++ b/group_vars/relay.yml
@@ -1,10 +1,4 @@
---
-network_dns_servers:
- - 172.20.20.10
- - 172.20.21.7
- - 172.20.21.8
-network_dns_search:
- - foo.sh
network_default_gateway: 37.16.96.145
network_vip_interfaces:
@@ -41,3 +35,4 @@ firewall_in:
- {proto: tcp, port: 443}
- {proto: tcp, port: 636}
- {proto: tcp, port: 6514}
+ - {proto: tcp, port: 9100}
diff --git a/group_vars/sane.yml b/group_vars/sane.yml
new file mode 100644
index 0000000..a6636ac
--- /dev/null
+++ b/group_vars/sane.yml
@@ -0,0 +1,5 @@
+---
+firewall_in:
+ - {proto: tcp, port: 22, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 443, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/shell.yml b/group_vars/shell.yml
index cefac15..6300cab 100644
--- a/group_vars/shell.yml
+++ b/group_vars/shell.yml
@@ -1,6 +1,4 @@
---
-
-# beef up shell hosts
dsk_size: 40
mem_size: 8192
num_cpus: 4
@@ -9,4 +7,10 @@ firewall_in:
- {proto: tcp, port: 22}
- {proto: tcp, port: 80}
- {proto: tcp, port: 443}
- - {proto: tcp, port: 4949, from: [81.175.130.44/32]}
+ - {proto: tcp, port: 9100, from: [212.149.248.65/32]}
+
+ssh_hostnames:
+ - shell.foo.sh
+
+sssd_allow_groups:
+ - foosh
diff --git a/group_vars/sqldb.yml b/group_vars/sqldb.yml
index df3c506..5848832 100644
--- a/group_vars/sqldb.yml
+++ b/group_vars/sqldb.yml
@@ -1,6 +1,8 @@
---
+mem_size: 4096
datadisks:
- {size: 20, type: nvme}
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 3306, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/group_vars/static.yml b/group_vars/static.yml
index 24c3e3a..f211563 100644
--- a/group_vars/static.yml
+++ b/group_vars/static.yml
@@ -2,4 +2,7 @@
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- {proto: tcp, port: 443, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
+
+sssd_allow_groups:
+ - root
diff --git a/group_vars/vmhost.yml b/group_vars/vmhost.yml
index c611eea..0b7f509 100644
--- a/group_vars/vmhost.yml
+++ b/group_vars/vmhost.yml
@@ -1,4 +1,4 @@
---
firewall_in:
- {proto: tcp, port: 22, from: [172.20.20.0/22]}
- - {proto: tcp, port: 4949, from: [172.20.20.0/22]}
+ - {proto: tcp, port: 9100, from: [172.20.20.0/22]}
diff --git a/host_vars/audiobooks02.home.foo.sh.yml b/host_vars/audiobooks02.home.foo.sh.yml
new file mode 100644
index 0000000..d6cf2c6
--- /dev/null
+++ b/host_vars/audiobooks02.home.foo.sh.yml
@@ -0,0 +1,6 @@
+---
+vmhost: vmhost02.home.foo.sh
+network_interfaces:
+ - device: eth0
+ vlan: 20
+ mac: "52:54:00:ac:dc:48"
diff --git a/host_vars/backup02.home.foo.sh.yml b/host_vars/backup02.home.foo.sh.yml
index 651b34f..44d02d4 100644
--- a/host_vars/backup02.home.foo.sh.yml
+++ b/host_vars/backup02.home.foo.sh.yml
@@ -6,5 +6,5 @@ network_interfaces:
mac: 52:54:00:ac:dc:50
datadisks:
- {size: 1000}
-passthrough_devices:
- - "07:04.0"
+virt_install_devices:
+ - "02:04.0"
diff --git a/host_vars/dna-gw01.home.foo.sh.yml b/host_vars/dna-gw01.home.foo.sh.yml
index d7c25b9..481ae6c 100644
--- a/host_vars/dna-gw01.home.foo.sh.yml
+++ b/host_vars/dna-gw01.home.foo.sh.yml
@@ -10,3 +10,5 @@ network_interfaces:
- device: vio1
vlan: 103
proto: none
+vip11_priority: 240
+vip12_priority: 120
diff --git a/host_vars/dna-gw02.home.foo.sh.yml b/host_vars/dna-gw02.home.foo.sh.yml
index fae4c34..d9977c7 100644
--- a/host_vars/dna-gw02.home.foo.sh.yml
+++ b/host_vars/dna-gw02.home.foo.sh.yml
@@ -10,3 +10,5 @@ network_interfaces:
- device: vio1
vlan: 103
proto: none
+vip11_priority: 120
+vip12_priority: 240
diff --git a/host_vars/gitea-runner02.home.foo.sh.yml b/host_vars/forgejo02.home.foo.sh.yml
similarity index 75%
rename from host_vars/gitea-runner02.home.foo.sh.yml
rename to host_vars/forgejo02.home.foo.sh.yml
index 617957c..72e305b 100644
--- a/host_vars/gitea-runner02.home.foo.sh.yml
+++ b/host_vars/forgejo02.home.foo.sh.yml
@@ -3,4 +3,4 @@ vmhost: vmhost02.home.foo.sh
network_interfaces:
- device: eth0
vlan: 20
- mac: 52:54:00:ac:dc:7c
+ mac: 52:54:00:ac:dc:80
diff --git a/host_vars/zm02.home.foo.sh.yml b/host_vars/frigate02.home.foo.sh.yml
similarity index 79%
rename from host_vars/zm02.home.foo.sh.yml
rename to host_vars/frigate02.home.foo.sh.yml
index 340464a..1f47a47 100644
--- a/host_vars/zm02.home.foo.sh.yml
+++ b/host_vars/frigate02.home.foo.sh.yml
@@ -3,7 +3,7 @@ vmhost: vmhost02.home.foo.sh
network_interfaces:
- device: eth0
vlan: 20
- mac: "52:54:00:ac:dc:4c"
+ mac: "52:54:00:ac:dc:8c"
nameservers: []
- device: eth1
vlan: 26
@@ -11,3 +11,5 @@ network_interfaces:
netmask: 255.255.255.0
proto: static
nameservers: [172.20.26.1, 172.20.26.3]
+virt_install_devices:
+ - 004.002
diff --git a/host_vars/fsol-gw01.home.foo.sh.yml b/host_vars/fsol-gw01.home.foo.sh.yml
index 798ef20..d6e9acd 100644
--- a/host_vars/fsol-gw01.home.foo.sh.yml
+++ b/host_vars/fsol-gw01.home.foo.sh.yml
@@ -15,6 +15,7 @@ network_interfaces:
- device: vio2
vlan: 103
proto: dhcp
+ rdomain: 1
- device: vio3
vlan: 102
proto: none
diff --git a/host_vars/fsol-gw02.home.foo.sh.yml b/host_vars/fsol-gw02.home.foo.sh.yml
index 88cce43..9b00140 100644
--- a/host_vars/fsol-gw02.home.foo.sh.yml
+++ b/host_vars/fsol-gw02.home.foo.sh.yml
@@ -15,6 +15,7 @@ network_interfaces:
- device: vio2
vlan: 103
proto: dhcp
+ rdomain: 1
- device: vio3
vlan: 102
proto: none
diff --git a/host_vars/homeassistant01.home.foo.sh.yml b/host_vars/homeassistant01.home.foo.sh.yml
index c9c1d5f..e952693 100644
--- a/host_vars/homeassistant01.home.foo.sh.yml
+++ b/host_vars/homeassistant01.home.foo.sh.yml
@@ -5,6 +5,10 @@ network_interfaces:
vlan: 20
mac: 52:54:00:ac:dc:73
- device: eth1
+ vlan: 27
+ - device: eth2
vlan: 30
virt_install_devices:
- - 003.002
+ - 0b05:190e
+ - 10c4:ea60
+ - /dev/ttyUSB0
diff --git a/host_vars/ldap01.home.foo.sh.yml b/host_vars/ldap01.home.foo.sh.yml
index 8951d67..a64ca14 100644
--- a/host_vars/ldap01.home.foo.sh.yml
+++ b/host_vars/ldap01.home.foo.sh.yml
@@ -5,6 +5,6 @@ network_interfaces:
vlan: 20
mac: 52:54:00:ac:dc:1f
datadisks:
- - {size: 10}
+ - {size: 10, type: nvme}
ldap_master: true
diff --git a/host_vars/gitea02.home.foo.sh.yml b/host_vars/mirror02.home.foo.sh.yml
similarity index 75%
rename from host_vars/gitea02.home.foo.sh.yml
rename to host_vars/mirror02.home.foo.sh.yml
index 56bb5fa..d8c639e 100644
--- a/host_vars/gitea02.home.foo.sh.yml
+++ b/host_vars/mirror02.home.foo.sh.yml
@@ -3,4 +3,4 @@ vmhost: vmhost02.home.foo.sh
network_interfaces:
- device: eth0
vlan: 20
- mac: 52:54:00:ac:dc:78
+ mac: 52:54:00:ac:dc:14
diff --git a/host_vars/nms02.home.foo.sh.yml b/host_vars/nms02.home.foo.sh.yml
index 4e1a686..cb1b86b 100644
--- a/host_vars/nms02.home.foo.sh.yml
+++ b/host_vars/nms02.home.foo.sh.yml
@@ -17,4 +17,4 @@ network_interfaces:
netmask: 255.255.255.248
proto: static
-vip25_priority: 0
+vip25_priority: 1
diff --git a/host_vars/oci-node01.home.foo.sh.yml b/host_vars/oci-node01.home.foo.sh.yml
index 0cc5278..9116611 100644
--- a/host_vars/oci-node01.home.foo.sh.yml
+++ b/host_vars/oci-node01.home.foo.sh.yml
@@ -1,5 +1,7 @@
---
vmhost: vmhost01.home.foo.sh
+datadisks:
+ - {size: 10, type: nvme}
network_interfaces:
- device: eth0
vlan: 20
diff --git a/host_vars/mirror01.home.foo.sh.yml b/host_vars/prometheus01.home.foo.sh.yml
similarity index 74%
rename from host_vars/mirror01.home.foo.sh.yml
rename to host_vars/prometheus01.home.foo.sh.yml
index bc25b7a..e88cf8b 100644
--- a/host_vars/mirror01.home.foo.sh.yml
+++ b/host_vars/prometheus01.home.foo.sh.yml
@@ -3,4 +3,4 @@ vmhost: vmhost01.home.foo.sh
network_interfaces:
- device: eth0
vlan: 20
- mac: 52:54:00:ac:dc:13
+ mac: "52:54:00:ac:dc:83"
diff --git a/host_vars/sane02.home.foo.sh.yml b/host_vars/sane02.home.foo.sh.yml
new file mode 100644
index 0000000..2c0bdad
--- /dev/null
+++ b/host_vars/sane02.home.foo.sh.yml
@@ -0,0 +1,8 @@
+---
+vmhost: vmhost02.home.foo.sh
+network_interfaces:
+ - device: eth0
+ vlan: 20
+ mac: "52:54:00:ac:dc:88"
+virt_install_devices:
+ - 001.003
diff --git a/hosts.yml b/hosts.yml
index ba6f047..4c3f054 100644
--- a/hosts.yml
+++ b/hosts.yml
@@ -3,6 +3,9 @@ adm:
hosts:
adm01.home.foo.sh:
adm02.home.foo.sh:
+audiobooks:
+ hosts:
+ audiobooks02.home.foo.sh:
backup:
hosts:
backup02.home.foo.sh:
@@ -13,25 +16,33 @@ dnagw:
hosts:
dna-gw01.home.foo.sh:
dna-gw02.home.foo.sh:
+forgejo:
+ hosts:
+ forgejo02.home.foo.sh:
+ vars:
+ forgejo_version: "11.0.0"
+frigate:
+ hosts:
+ frigate02.home.foo.sh:
+ vars:
+ frigate_version: "0.15.1"
fsolgw:
hosts:
fsol-gw01.home.foo.sh:
fsol-gw02.home.foo.sh:
-gitea:
- hosts:
- gitea02.home.foo.sh:
- vars:
- gitea_version: "1.19.4"
-gitearunner:
- hosts:
- gitea-runner02.home.foo.sh:
- vars:
- gitea_runner_version: "0.2.3"
homeassistant:
hosts:
homeassistant01.home.foo.sh:
vars:
- homeassistant_version: "2023.7"
+ homeassistant_version: "2025.4"
+ homeassistant_integrations:
+ - name: electrolux_status
+ repo: https://github.com/albaintor/homeassistant_electrolux_status.git
+ version: v2.0.10
+ - name: espsomfy_rts
+ repo: https://github.com/rstrouse/ESPSomfy-RTS-HA.git
+ version: v2.4.7
+ nodered_version: 4.0.9
influxdb:
hosts:
influxdb01.home.foo.sh:
@@ -45,12 +56,14 @@ log:
mail:
hosts:
mail02.home.foo.sh:
+ vars:
+ opendkim_selector: 20250101
minecraft:
hosts:
minecraft01.home.foo.sh:
mirror:
hosts:
- mirror01.home.foo.sh:
+ mirror02.home.foo.sh:
mongodb:
hosts:
mongodb01.home.foo.sh:
@@ -64,6 +77,8 @@ nms:
hosts:
nms01.home.foo.sh:
nms02.home.foo.sh:
+ vars:
+ snmp_exporter_version: "0.29.0"
ns:
hosts:
ns01.home.foo.sh:
@@ -74,20 +89,34 @@ ocinode:
oci-node01.home.foo.sh:
oci-node02.home.foo.sh:
vars:
- grafana_version: "10.0.2"
- rocketchat_version: "6.2.10"
- roundcube_version: "1.6.1"
+ grafana_version: "11.6.1"
+ rocketchat_version: "7.5.1"
+ roundcube_version: "1.6.10"
print:
hosts:
print01.home.foo.sh:
+prometheus:
+ hosts:
+ prometheus01.home.foo.sh:
+ vars:
+ mysqld_exporter_version: "0.17.2"
+ nginx_exporter_version: "1.4.1"
proxy:
hosts:
proxy01.home.foo.sh:
proxy02.home.foo.sh:
+redis:
+ hosts:
+ redis01.home.foo.sh:
relay:
hosts:
relay01.home.foo.sh:
relay02.home.foo.sh:
+sane:
+ hosts:
+ sane02.home.foo.sh:
+ vars:
+ scanservjs_version: "v3.0.3"
shell:
hosts:
shell01.foo.sh:
@@ -103,23 +132,15 @@ vmhost:
hosts:
vmhost01.home.foo.sh:
vmhost02.home.foo.sh:
-zm:
- hosts:
- zm02.home.foo.sh:
sftpbackup:
children:
- collab:
ldap:
+ mongodb:
sqldb:
-vultr:
- hosts:
- atl01.vultr.foo.sh:
-
fedora:
children:
- gitearunner:
openbsd:
children:
backup:
@@ -129,27 +150,31 @@ openbsd:
mqtt:
ns:
proxy:
+ redis:
relay:
rocky8:
children:
collab:
+rocky9:
+ children:
+ adm:
+ audiobooks:
+ forgejo:
+ frigate:
homeassistant:
+ influxdb:
+ ldap:
mail:
minecraft:
+ mirror:
+ mongodb:
nas:
nms:
ocinode:
print:
+ prometheus:
+ sane:
shell:
- zm:
-rocky9:
- children:
- adm:
- gitea:
- influxdb:
- ldap:
- mirror:
- mongodb:
sqldb:
static:
vmhost:
diff --git a/playbooks/adm.yml b/playbooks/adm.yml
index 9833c14..3c2bd6c 100644
--- a/playbooks/adm.yml
+++ b/playbooks/adm.yml
@@ -18,7 +18,7 @@
name: /export
src: LABEL=/export
fstype: xfs
- opts: noatime,noexec,nosuid,nodev
+ opts: noatime,nosuid,nodev
passno: "0"
dump: "0"
state: mounted
@@ -27,10 +27,15 @@
- base
- ansible_host
- certbot
+ - cups
+ - sshca
+ - ssh_known_hosts
- role: keytab
- principals:
+ keytab_principals:
- "host/{{ inventory_hostname }}@{{ kerberos_realm }}"
- nfs_client
+ - role: autofs
+ autofs_home: false
- sssd
- mkhomedir
- rpm_build
@@ -42,15 +47,21 @@
name: "{{ item }}"
state: installed
with_items:
+ - emacs-nox # more editors
- httpd-tools # htpasswd
- knot-utils # kdig (dns over tls)
- libvirt-client # kvm host client
- make # generic building
- mariadb # mariadb client tools
+ - mosquitto # mqtt reading
+ - nano # more editors
+ - nmap # check for open ports
- nsd # check dns zone files
- podman # building containers
- pylint # python linting
- python3-flake8 # python linting
+ - speedtest-cli # testing network speed
+ - ShellCheck # shell script linting
- virt-install # install kvm guests
- wget # still in backbone for downloads
- whois # read whois data
@@ -63,6 +74,67 @@
Host shell??.foo.sh
CheckHostIP no
dest: /root/.ssh/config
- mode: 0600
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+ - name: Clone dns repo
+ ansible.builtin.git:
+ dest: /export/dns
+ repo: https://adm01.home.foo.sh/dns.git
+ update: true
+ version: master
+ environment:
+ GIT_SSL_CAINFO: "{{ tls_certs }}/ca.crt"
+ GIT_SSL_CERT: "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ GIT_SSL_KEY: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ when: 'inventory_hostname != "adm01.home.foo.sh"'
+ - name: Link dns repo
+ ansible.builtin.file:
+ dest: /srv/dns
+ src: /export/dns
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+ - name: Add cron job to sync dns repo
+ ansible.builtin.cron:
+ name: sync dns repository
+ job: >-
+ GIT_SSL_CAINFO="{{ tls_certs }}/ca.crt"
+ GIT_SSL_CERT="{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ GIT_SSL_KEY="{{ tls_private }}/{{ inventory_hostname }}.key"
+ git -C /srv/dns pull -q
+ minute: "02"
+ when: 'inventory_hostname != "adm01.home.foo.sh"'
+ - name: Links dns repo to web
+ ansible.builtin.file:
+ dest: "/srv/web/{{ inventory_hostname }}/dns.git"
+ src: /srv/dns/.git
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+ - name: Add mqtt-tail script
+ ansible.builtin.copy:
+ dest: /usr/local/bin/mqtt-tail
+ content: |
+ #!/bin/sh
+ set -eu
+ if [ -n "${1:-}" ]; then
+ topic="$1"
+ shift
+ else
+ topic="#"
+ fi
+ if [ $# -ne 0 ]; then
+ echo "Usage: $(basename "$0") [topic]" 1>&2
+ exit 1
+ fi
+ exec mosquitto_sub -h mqtt02.home.foo.sh -v -t "$topic" \
+ --cafile "{{ tls_certs }}/ca.crt" \
+ --cert "{{ tls_certs }}/{{ inventory_hostname }}.crt" \
+ --key "{{ tls_private }}/{{ inventory_hostname }}.key" \
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/playbooks/audiobooks.yml b/playbooks/audiobooks.yml
new file mode 100644
index 0000000..3d8ce19
--- /dev/null
+++ b/playbooks/audiobooks.yml
@@ -0,0 +1,25 @@
+---
+- name: Deploy KVM virtual machines
+ ansible.builtin.import_playbook: include/deploy-kvm-guest.yml
+ vars:
+ myhosts: audiobooks
+
+- name: Configure instance
+ hosts: audiobooks
+ user: root
+ gather_facts: true
+
+ pre_tasks:
+ - name: Mount /export
+ ansible.posix.mount:
+ name: /export
+ src: LABEL=/export
+ fstype: xfs
+ opts: noatime,nosuid,nodev
+ passno: "0"
+ dump: "0"
+ state: mounted
+
+ roles:
+ - base
+ - audiobookshelf
diff --git a/playbooks/backup.yml b/playbooks/backup.yml
index 3973aab..3712638 100644
--- a/playbooks/backup.yml
+++ b/playbooks/backup.yml
@@ -15,7 +15,7 @@
name: /export
src: /dev/sd1a
fstype: ffs
- opts: rw,softdep,noatime
+ opts: rw,softdep,noatime,noexec,nosuid,nodev
passno: "1"
dump: "2"
state: mounted
@@ -25,5 +25,10 @@
roles:
- base
- - backup_server
- - sftpbackup
+ - backup_base
+ - backup_bitbucket
+ - backup_github
+ - role: rclone
+ rclone_hostgroup: sftpbackup
+ rclone_service: backup
+ - rsync_backup
diff --git a/playbooks/collab.yml b/playbooks/collab.yml
index 6533222..89edf92 100644
--- a/playbooks/collab.yml
+++ b/playbooks/collab.yml
@@ -28,9 +28,9 @@
- collab
- mod_auth_gssapi
- role: keytab
- keytab: /etc/httpd/httpd.keytab
- principals: HTTP/collab.foo.sh@FOO.SH
- group: apache
+ keytab_path: /etc/httpd/httpd.keytab
+ keytab_principals: HTTP/collab.foo.sh@FOO.SH
+ keytab_group: apache
- ldap
tasks:
@@ -38,7 +38,7 @@
ansible.builtin.copy:
content: "RedirectMatch permanent \"^/$\" /collab/\n"
dest: "/etc/httpd/conf.local.d/redirects.conf"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
@@ -61,7 +61,7 @@
dest: /srv/wikis/collab/htdocs/.htaccess
owner: collab
group: collab
- mode: 0660
+ mode: "0660"
seuser: _default
setype: _default
diff --git a/playbooks/dna-gw.yml b/playbooks/dna-gw.yml
index 00f50ea..17cb310 100644
--- a/playbooks/dna-gw.yml
+++ b/playbooks/dna-gw.yml
@@ -14,29 +14,14 @@
roles:
- base
- - ifstated
- dhcpd
- - nginx/server
- - role: nginx/site
- site: gw.home.foo.sh
+ - nginx
+ - role: nginx_site
+ nginx_site_name: gw.home.foo.sh
- tftp
- websockify
tasks:
- - name: Use configured dns servers and domain name
- ansible.builtin.copy:
- dest: /etc/dhclient.conf
- content: "ignore domain-name-servers, domain-name;\n"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
-
- - name: Disable resolvd
- ansible.builtin.service:
- name: resolvd
- state: stopped
- enabled: false
-
- name: Enable ip forwarding
ansible.posix.sysctl:
name: "{{ item }}"
@@ -49,11 +34,49 @@
- name: Run handlers to get interfaces configured
ansible.builtin.meta: flush_handlers
+ - name: Import ifstated role
+ ansible.builtin.import_role:
+ name: ifstated
+
+ - name: Copy DNS private key
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/dns.home.foo.sh.key"
+ src: "{{ item }}"
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ with_first_found:
+ - /srv/letsencrypt/live/dns.home.foo.sh/privkey.pem
+ - "/srv/ca/private/{{ inventory_hostname }}.key"
+ tags: certificates
+ notify: Restart unbound
+
+ - name: Copy DNS certificate and ca cert
+ ansible.builtin.copy:
+ dest: "{{ tls_certs }}/dns.home.foo.sh.crt"
+ src: "{{ item }}"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ with_first_found:
+ - /srv/letsencrypt/live/dns.home.foo.sh/fullchain.pem
+ - "/srv/ca/certs/hosts/{{ inventory_hostname }}.crt"
+ tags: certificates
+ notify: Restart unbound
+
+ - name: Import unbound role
+ ansible.builtin.import_role:
+ name: unbound
+
+ - name: Import unbound_exporter role
+ ansible.builtin.import_role:
+ name: unbound_exporter
+
- name: Create tftp boot directories
ansible.builtin.file:
path: /srv/tftpboot/etc
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -64,25 +87,25 @@
stty com0 115200
set tty com0
boot tftp:bsd.rd
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
- name: Create tftp pxeboot loader for OpenBSD installs
ansible.builtin.get_url:
- url: "https://ftp.eu.openbsd.org/pub/OpenBSD/7.3/amd64/pxeboot"
- checksum: sha1:161b36d4ae3d786aa98c4836abba25f2bca8979d
+ url: "https://ftp.eu.openbsd.org/pub/OpenBSD/7.6/amd64/pxeboot"
+ checksum: sha1:c696836c1e6cc67c6c31f6ceb5daaaa4ec0632b7
dest: /srv/tftpboot/pxeboot
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
- name: Create tftp ramdisk for OpenBSD installs
ansible.builtin.get_url:
- url: "https://ftp.eu.openbsd.org/pub/OpenBSD//7.3/amd64/bsd.rd"
- checksum: sha1:72b46ad8e97b2082d145a739264e818dcd154021
+ url: "https://ftp.eu.openbsd.org/pub/OpenBSD/7.6/amd64/bsd.rd"
+ checksum: sha1:f690655c768ec9ef208188921ac53634a9233aca
dest: /srv/tftpboot/bsd.rd
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -91,7 +114,7 @@
url: "https://boot.foo.sh/openbsd/install.conf"
checksum: sha1:f6270708dad3f759df02eefeab300d9b8670f3d4
dest: /srv/tftpboot/install.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -113,50 +136,7 @@
}
}
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
-
- - name: Copy DNS private key
- ansible.builtin.copy:
- dest: "{{ tls_private }}/dns.home.foo.sh.key"
- src: "{{ item }}"
- mode: 0600
- owner: root
- group: "{{ ansible_wheel }}"
- with_first_found:
- - /srv/letsencrypt/live/dns.home.foo.sh/privkey.pem
- - "/srv/ca/private/{{ inventory_hostname }}.key"
- tags: certificates
- notify: Restart unbound
-
- - name: Copy DNS certificate and ca cert
- ansible.builtin.copy:
- dest: "{{ tls_certs }}/dns.home.foo.sh.crt"
- src: "{{ item }}"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- with_first_found:
- - /srv/letsencrypt/live/dns.home.foo.sh/fullchain.pem
- - "/srv/ca/certs/hosts/{{ inventory_hostname }}.crt"
- tags: certificates
- notify: Restart unbound
-
- - name: Copy DNS zone files
- ansible.builtin.copy:
- dest: "/var/unbound/db/{{ item }}"
- src: "/srv/dns/{{ item }}"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- tags: dns
- notify: Restart unbound
- with_items:
- - 20.172.in-addr.arpa
- - home.foo.sh
-
- - name: Import unbound role
- ansible.builtin.import_role:
- name: unbound
diff --git a/playbooks/gitea.yml b/playbooks/forgejo.yml
similarity index 90%
rename from playbooks/gitea.yml
rename to playbooks/forgejo.yml
index 72fec32..ab0ac1b 100644
--- a/playbooks/gitea.yml
+++ b/playbooks/forgejo.yml
@@ -2,10 +2,10 @@
- name: Deploy KVM virtual machines
ansible.builtin.import_playbook: include/deploy-kvm-guest.yml
vars:
- myhosts: gitea
+ myhosts: forgejo
- name: Configure instance
- hosts: gitea
+ hosts: forgejo
user: root
gather_facts: true
@@ -25,4 +25,4 @@
roles:
- base
- - gitea
+ - forgejo
diff --git a/playbooks/zm.yml b/playbooks/frigate.yml
similarity index 50%
rename from playbooks/zm.yml
rename to playbooks/frigate.yml
index f96065c..83bc482 100644
--- a/playbooks/zm.yml
+++ b/playbooks/frigate.yml
@@ -2,10 +2,10 @@
- name: Deploy KVM virtual machines
ansible.builtin.import_playbook: include/deploy-kvm-guest.yml
vars:
- myhosts: zm
+ myhosts: frigate
- name: Configure instance
- hosts: zm
+ hosts: frigate
user: root
gather_facts: true
@@ -13,74 +13,54 @@
- "{{ ansible_private }}/vars.yml"
pre_tasks:
- - name: Mount /export
+ - name: Mount datadirectories
ansible.posix.mount:
- name: /export
- src: LABEL=/export
+ name: "/export/frigate/{{ item }}"
+ src: "LABEL={{ item }}"
fstype: xfs
opts: noatime,noexec,nosuid,nodev
passno: "0"
dump: "0"
state: mounted
+ with_items:
+ - config
+ - media
roles:
- base
- mod_auth_gssapi
- role: keytab
- keytab: /etc/httpd/httpd.keytab
- principals: HTTP/zm.foo.sh@FOO.SH
- group: apache
+ keytab_path: /etc/httpd/httpd.keytab
+ keytab_principals: HTTP/cctv.foo.sh@FOO.SH
+ keytab_group: apache
tasks:
- - name: Run handlers to get interfaces configured
- ansible.builtin.meta: flush_handlers
-
- # TODO: this should really be fixed
- - name: Put selinux in permissive state
- ansible.posix.selinux:
- policy: targeted
- state: permissive
-
- - name: Copy DNS zone files
- ansible.builtin.copy:
- dest: "/var/lib/unbound/{{ item }}"
- src: "/srv/dns/{{ item }}"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- tags: dns
- notify: Restart unbound
- with_items:
- - 26.20.172.in-addr.arpa
- - cam.foo.sh
-
- name: Include unbound role
ansible.builtin.import_role:
name: unbound
- - name: Include dhcpd and zoneminder roles
+ - name: Run handlers to get interfaces configured
+ ansible.builtin.meta: flush_handlers
+
+ - name: Include dhcpd role
ansible.builtin.include_role:
- name: "{{ item }}"
- with_items:
- - dhcpd
- - zoneminder
+ name: dhcpd
- - name: Install extra packages for debugging
- ansible.builtin.package:
- name: rtmpdump
- state: installed
+ - name: Include frigate role
+ ansible.builtin.include_role:
+ name: frigate
- - name: Require authentication for zoneminder
+ - name: Require authentication for frigate
ansible.builtin.copy:
- dest: /etc/httpd/conf.local.d/zoneminder-auth.conf
+ dest: /etc/httpd/conf.local.d/frigate-auth.conf
content: |
-
+
AuthType GSSAPI
- GssapiBasicAuth Off
+ GssapiBasicAuth On
AuthName "Password Required"
Require valid-user
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
diff --git a/playbooks/fsol-gw.yml b/playbooks/fsol-gw.yml
index 7d6efe8..639bd27 100644
--- a/playbooks/fsol-gw.yml
+++ b/playbooks/fsol-gw.yml
@@ -12,13 +12,6 @@
vars_files:
- "{{ ansible_private }}/vars.yml"
- pre_tasks:
- - name: Disable resolvd service
- ansible.builtin.service:
- name: resolvd
- state: stopped
- enabled: false
-
tasks:
- name: Enable IP forwarding
ansible.posix.sysctl:
@@ -30,16 +23,19 @@
- net.inet6.ip6.forwarding
- name: Manually set DNS servers
ansible.builtin.copy:
- dest: /etc/dhclient.conf
- content: "ignore domain-name-servers, domain-name;\n"
- mode: 0644
+ dest: /etc/dhcpleased.conf
+ content: |
+ interface vio2 {
+ ignore dns
+ }
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
- name: Create pfsync interface
ansible.builtin.copy:
dest: /etc/hostname.pfsync0
content: "up syncdev vio1\n"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/playbooks/gitea-runner.yml b/playbooks/gitea-runner.yml
deleted file mode 100644
index c87211c..0000000
--- a/playbooks/gitea-runner.yml
+++ /dev/null
@@ -1,14 +0,0 @@
----
-- name: Deploy KVM virtual machines
- ansible.builtin.import_playbook: include/deploy-kvm-guest.yml
- vars:
- myhosts: gitearunner
-
-- name: Configure instance
- hosts: gitearunner
- user: root
- gather_facts: true
-
- roles:
- - base
- - gitea_runner
diff --git a/playbooks/homeassistant.yml b/playbooks/homeassistant.yml
index 965d818..1baf203 100644
--- a/playbooks/homeassistant.yml
+++ b/playbooks/homeassistant.yml
@@ -9,6 +9,9 @@
user: root
gather_facts: true
+ vars_files:
+ - "{{ ansible_private }}/vars.yml"
+
pre_tasks:
- name: Mount /export
ansible.posix.mount:
@@ -24,3 +27,4 @@
- base
- ldap
- homeassistant
+ - nodered
diff --git a/playbooks/include/deploy-kvm-guest.yml b/playbooks/include/deploy-kvm-guest.yml
index 4f763fd..5464cd5 100644
--- a/playbooks/include/deploy-kvm-guest.yml
+++ b/playbooks/include/deploy-kvm-guest.yml
@@ -9,7 +9,7 @@
char: "{{ 'bcdefghijklmnopqrstuvwxyz'|list }}"
console_log: "/var/log/libvirt/qemu/{{ inventory_hostname }}.console.log"
- os_disk_image: "/srv/libvirt/ssd/{{ inventory_hostname }}.a.img"
+ os_disk_image: "/srv/libvirt/os/{{ inventory_hostname }}.a.img"
dsk_opts: bus=virtio,cache=none,device=disk,format=raw,sparse=no
inject: >-
@@ -75,7 +75,7 @@
echo '{{ root_pubkey }}' > /root/.ssh/authorized_keys
%end
dest: "{{ tmpdir.path }}/include.ks"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
delegate_to: "{{ vmhost }}"
@@ -99,7 +99,11 @@
{% endif -%}
{% if virt_install_devices is defined -%}
{% for dev in virt_install_devices -%}
+ {% if dev | regex_search('^/dev/tty') -%}
+ --serial dev,path={{ dev }}
+ {% else -%}
--hostdev {{ dev }} \
+ {% endif -%}
{% endfor -%}
{% else -%}
--controller usb,model=none \
diff --git a/playbooks/ldap.yml b/playbooks/ldap.yml
index 7379a52..6c97c98 100644
--- a/playbooks/ldap.yml
+++ b/playbooks/ldap.yml
@@ -19,7 +19,7 @@
passno: "0"
dump: "0"
state: mounted
- when: ldap_master is defined
+ when: ldap_master
vars_files:
- "{{ ansible_private }}/vars.yml"
@@ -28,8 +28,8 @@
- base
- ldap_server
- role: kadmin
- when: ldap_master is defined
+ when: ldap_master
- role: ldap_netdb
- when: ldap_master is defined
+ when: ldap_master
- role: ldap_gravatar
- when: ldap_master is defined
+ when: ldap_master
diff --git a/playbooks/log.yml b/playbooks/log.yml
index 13bfd5d..50caf5f 100644
--- a/playbooks/log.yml
+++ b/playbooks/log.yml
@@ -15,7 +15,7 @@
name: /export
src: /dev/sd1a
fstype: ffs
- opts: rw,softdep,noatime
+ opts: rw,softdep,noatime,noexec,nosuid,nodev
passno: "1"
dump: "2"
state: mounted
diff --git a/playbooks/mail.yml b/playbooks/mail.yml
index 072587d..c3c8041 100644
--- a/playbooks/mail.yml
+++ b/playbooks/mail.yml
@@ -26,18 +26,19 @@
roles:
- base
- role: keytab
- principals:
+ keytab_principals:
- "host/{{ inventory_hostname }}@{{ kerberos_realm }}"
- "smtp/{{ mail_server }}@{{ kerberos_realm }}"
- nfs_client
- sssd
- autofs
- dovecot
- - role: nginx/server
- - role: nginx/site
- site: "{{ mail_server }}"
- redirect: https://webmail.foo.sh/
+ - role: nginx
+ - role: nginx_site
+ nginx_site_name: "{{ mail_server }}"
+ nginx_site_redirect: https://webmail.foo.sh/
- grossd
+ - opendkim
- spamassassin
- spamassassin_clamav
- spamassassin_ixhash
diff --git a/playbooks/manual/check-updates.yml b/playbooks/manual/check-updates.yml
new file mode 100644
index 0000000..1045eb0
--- /dev/null
+++ b/playbooks/manual/check-updates.yml
@@ -0,0 +1,23 @@
+---
+- hosts: all
+ gather_facts: true
+ tasks:
+ - name: Check updates (Linux)
+ ansible.builtin.command:
+ argv:
+ - dnf
+ - -q
+ - check-update
+ register: result
+ changed_when: result.rc == 100
+ failed_when: result.rc not in [0, 100]
+ when: ansible_os_family == "RedHat"
+
+ - name: Check updates (OpenBSD)
+ ansible.builtin.command:
+ argv:
+ - syspatch
+ - -c
+ register: result
+ changed_when: result.stdout != ""
+ when: ansible_os_family == "OpenBSD"
diff --git a/playbooks/minecraft.yml b/playbooks/minecraft.yml
index 9a88509..48b237c 100644
--- a/playbooks/minecraft.yml
+++ b/playbooks/minecraft.yml
@@ -15,7 +15,7 @@
name: /export
src: LABEL=/export
fstype: xfs
- opts: noatime
+ opts: noatime,noexec,nosuid,nodev
passno: "0"
dump: "0"
state: mounted
diff --git a/playbooks/mirror.yml b/playbooks/mirror.yml
index 7300be7..8be9d04 100644
--- a/playbooks/mirror.yml
+++ b/playbooks/mirror.yml
@@ -26,26 +26,30 @@
roles:
- base
- mirror/base
- - mirror/thinlinc
- - role: mirror/reportmirror
- hostname: mirrors.foo.sh
- mirrors: [epel, fedora]
- sitename: foo.sh
- password: "{{ report_mirror_pass }}"
+ - thinlinc_mirror
+ - role: reportmirror
+ reportmirror_hostname: mirrors.foo.sh
+ reportmirror_mirrors: [epel, fedora]
+ reportmirror_sitename: foo.sh
+ reportmirror_password: "{{ report_mirror_pass }}"
- role: mirror/sync
- label: fedora-epel
- source: "rsync://rsync.nic.funet.fi/ftp/pub/mirrors/\
- fedora.redhat.com/pub/epel"
- rsyncoptions:
- - "--exclude=SRPMS"
+ mirror_label: fedora-epel
+ mirror_source:
+ "rsync://rsync.nic.funet.fi/ftp/pub/mirrors/fedora.redhat.com/pub/epel"
+ mirror_rsyncoptions:
- "--exclude=debug"
+ - "--exclude=testing"
+ - "--exclude=aarch64"
+ - "--exclude=ppc64le"
+ - "--exclude=s390x"
+ - "--exclude=source"
- "--delete-excluded"
- postcmd: python3 /usr/local/bin/report_mirror
+ mirror_postcmd: python3 /usr/local/bin/report_mirror
- role: mirror/sync
- label: fedora
- source: "rsync://rsync.nic.funet.fi/ftp/pub/mirrors/\
- fedora.redhat.com/pub/fedora/linux/"
- rsyncoptions:
+ mirror_label: fedora
+ mirror_source:
+ "rsync://rsync.nic.funet.fi/ftp/pub/mirrors/fedora.redhat.com/pub/fedora/linux/"
+ mirror_rsyncoptions:
- "--exclude=/atomic"
- "--exclude=/development"
- "--exclude=/releases/test"
@@ -58,12 +62,11 @@
- "--exclude=armhfp"
- "--exclude=debug"
- "--delete-excluded"
- postcmd: python3 /usr/local/bin/report_mirror
+ mirror_postcmd: python3 /usr/local/bin/report_mirror
- role: mirror/sync
- label: openbsd
- source: "rsync://rsync.nic.funet.fi/ftp/pub/mirrors/\
- ftp.openbsd.org/pub/OpenBSD/"
- rsyncoptions:
+ mirror_label: openbsd
+ mirror_source: "rsync://ftp.nluug.nl/openbsd/"
+ mirror_rsyncoptions:
- "--include=/?.?/"
- "--include=/?.?/amd64/"
- "--include=/?.?/amd64/*"
diff --git a/playbooks/mqtt.yml b/playbooks/mqtt.yml
index 1a37f6e..8a5c0b7 100644
--- a/playbooks/mqtt.yml
+++ b/playbooks/mqtt.yml
@@ -9,10 +9,15 @@
user: root
gather_facts: true
+ vars_files:
+ - "{{ ansible_private }}/vars.yml"
+
roles:
- base
- mosquitto
+ - ha_mqtt_configd
- telegraf
- - nginx/server
- - role: nginx/site
- site: iot.foo.sh
+ - nginx
+ - role: nginx_site
+ nginx_site_name: iot.foo.sh
+ - shelly_firmware
diff --git a/playbooks/nas.yml b/playbooks/nas.yml
index 4d451e7..22c11f2 100644
--- a/playbooks/nas.yml
+++ b/playbooks/nas.yml
@@ -18,7 +18,7 @@
name: /export/home
src: LABEL=home
fstype: xfs
- opts: noatime
+ opts: noatime,nodev
passno: "0"
dump: "0"
state: mounted
@@ -27,7 +27,7 @@
name: /export/roles
src: LABEL=roles
fstype: xfs
- opts: noatime
+ opts: noatime,nodev
passno: "0"
dump: "0"
state: mounted
@@ -38,20 +38,4 @@
- sssd
- nfs_server
- role: keytab
- principals: "nfs/{{ inventory_hostname }}@FOO.SH"
-
- tasks:
- - name: Copy exports file
- ansible.builtin.copy:
- dest: /etc/exports
- content: |
- /export/home 172.20.30.0/24(rw,root_squash,secure,sec=krb5p) \
- @nfsclients-rw(rw,root_squash,secure) \
- @nfsclients-ro(ro,root_squash,secure)
- /export/roles 172.20.30.0/24(rw,root_squash,secure,sec=krb5p) \
- @nfsclients-rw(rw,root_squash,secure) \
- @nfsclients-ro(ro,root_squash,secure)
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- notify: Restart nfs-server
+ keytab_principals: "nfs/{{ inventory_hostname }}@FOO.SH"
diff --git a/playbooks/nms.yml b/playbooks/nms.yml
index f5ac7a0..f326b55 100644
--- a/playbooks/nms.yml
+++ b/playbooks/nms.yml
@@ -25,12 +25,22 @@
roles:
- base
- - nginx/server
- - role: nginx/site
- site: oob.foo.sh
+ - cups
+ - nginx
+ - role: nginx_site
+ nginx_site_name: oob.foo.sh
+ nginx_site_plaintext: false
+ - role: keytab
+ keytab_principals:
+ - "host/{{ inventory_hostname }}@{{ kerberos_realm }}"
+ - nfs_client
+ - role: autofs
+ autofs_home: false
- sssd
- mkhomedir
- - tftp
+ - aten_pdu
+ - routeros
+ - snmp_exporter
tasks:
- name: Enable UDP rsyslog server
@@ -45,23 +55,14 @@
vars:
relay_domains: [foo.sh]
- - name: Copy DNS zone files
- ansible.builtin.copy:
- dest: "/var/lib/unbound/{{ item }}"
- src: "/srv/dns/{{ item }}"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- tags: dns
- notify: Restart unbound
- with_items:
- - 25.20.172.in-addr.arpa
- - oob.foo.sh
-
- name: Import unbound role
ansible.builtin.import_role:
name: unbound
+ - name: Import dhcpd role
+ ansible.builtin.import_role:
+ name: dhcpd
+
# convert this to role for restart support
- name: Enable NTP server for oob network
ansible.builtin.lineinfile:
@@ -74,10 +75,18 @@
name: "{{ item }}"
state: installed
with_items:
- - net-snmp-utils
- nmap
- rcs
- - scanssh
- - sslscan
- unzip
- wget
+
+ - name: Create sw-backup script
+ ansible.builtin.copy:
+ dest: /usr/local/bin/sw-backup
+ content: |
+ #!/bin/sh
+ set -eu
+ ssh "admin@${1}" /export > "/srv/backup/${1}.rsc"
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
diff --git a/playbooks/ns.yml b/playbooks/ns.yml
index 495e358..4642197 100644
--- a/playbooks/ns.yml
+++ b/playbooks/ns.yml
@@ -2,7 +2,7 @@
- name: Deploy KVM virtual machines
ansible.builtin.import_playbook: include/deploy-kvm-guest.yml
vars:
- myhosts: ns:!vultr
+ myhosts: ns:!atl01.vultr.foo.sh
- name: Configure instance
hosts: ns
@@ -15,9 +15,11 @@
roles:
- base
- nsd
- - role: nginx/server
- - role: nginx/site
- site: "{{ nsd_server }}"
- redirect: https://www.foo.sh/
+ - role: nginx
+ - role: nginx_site
+ nginx_site_name: "{{ nsd_server }}"
+ nginx_site_redirect: https://www.foo.sh/
- role: ifstated
when: "'vultr' not in group_names"
+ - role: blackbox_exporter
+ when: "inventory_hostname == 'atl01.vultr.foo.sh'"
diff --git a/playbooks/oci-node.yml b/playbooks/oci-node.yml
index 231a6c4..d67e62f 100644
--- a/playbooks/oci-node.yml
+++ b/playbooks/oci-node.yml
@@ -12,9 +12,25 @@
vars_files:
- "{{ ansible_private }}/vars.yml"
+ pre_tasks:
+ - name: Mount /export
+ ansible.posix.mount:
+ name: /export
+ src: LABEL=/export
+ fstype: xfs
+ opts: noatime,noexec,nosuid,nodev
+ passno: "0"
+ dump: "0"
+ state: mounted
+ when: ansible_fqdn == 'oci-node01.home.foo.sh'
+
roles:
- base
- authcheck
- grafana
+ - ipsilon
- kdc
- roundcube
+ - role: php4dvd
+ when: ansible_fqdn == 'oci-node01.home.foo.sh'
+ - rocketchat
diff --git a/playbooks/print.yml b/playbooks/print.yml
index d434c76..733aa88 100644
--- a/playbooks/print.yml
+++ b/playbooks/print.yml
@@ -14,10 +14,17 @@
roles:
- base
+ - role: keytab
+ keytab_principals:
+ - "host/{{ inventory_hostname }}@{{ kerberos_realm }}"
- sssd
- mkhomedir
tasks:
+ - name: Install unbound role
+ ansible.builtin.import_role:
+ name: unbound
+
- name: Run handlers to get interfaces configured
ansible.builtin.meta: flush_handlers
@@ -25,30 +32,20 @@
ansible.builtin.import_role:
name: dhcpd
- - name: Copy DNS zone files
- ansible.builtin.copy:
- dest: "/var/lib/unbound/{{ item }}"
- src: "/srv/dns/{{ item }}"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- tags: dns
- notify: restart unbound
- with_items:
- - 24.20.172.in-addr.arpa
- - print.foo.sh
-
- - name: Install unbound role
- ansible.builtin.import_role:
- name: unbound
-
- name: Install cups_server role
ansible.builtin.import_role:
name: cups_server
- name: Install keytab for CUPS
- ansible.builtin.import_role:
+ ansible.builtin.include_role:
name: keytab
vars:
- keytab: /etc/cups/cups.keytab
- principals: "HTTP/print.foo.sh@{{ kerberos_realm }}"
+ keytab_path: /etc/cups/cups.keytab
+ keytab_principals: "HTTP/print.foo.sh@{{ kerberos_realm }}"
+
+ - name: Enable postfix mail relay
+ ansible.builtin.import_role:
+ name: postfix
+ tasks_from: relay
+ vars:
+ relay_domains: [foo.sh]
diff --git a/playbooks/prometheus.yml b/playbooks/prometheus.yml
new file mode 100644
index 0000000..cef9acf
--- /dev/null
+++ b/playbooks/prometheus.yml
@@ -0,0 +1,30 @@
+---
+- name: Deploy KVM virtual machines
+ ansible.builtin.import_playbook: include/deploy-kvm-guest.yml
+ vars:
+ myhosts: prometheus
+
+- name: Configure instance
+ hosts: prometheus
+ user: root
+ gather_facts: true
+
+ vars_files:
+ - "{{ ansible_private }}/vars.yml"
+
+ pre_tasks:
+ - name: Mount /export
+ ansible.posix.mount:
+ name: /export
+ src: LABEL=/export
+ fstype: xfs
+ opts: noatime,noexec,nosuid,nodev
+ passno: "0"
+ dump: "0"
+ state: mounted
+
+ roles:
+ - base
+ - prometheus
+ - mysqld_exporter
+ - nginx_exporter
diff --git a/playbooks/proxy.yml b/playbooks/proxy.yml
index e625b08..da8b9b7 100644
--- a/playbooks/proxy.yml
+++ b/playbooks/proxy.yml
@@ -15,90 +15,116 @@
roles:
- base
- ifstated
- - nginx/server
- - role: nginx/site
- site: ca.foo.sh
- - role: nginx/site
- site: foo.monster
- - role: nginx/site
- site: tuiradc.fi
- redirect: https://facebook.com/TuiraDC
- - role: nginx/site
- site: www.tuiradc.fi
- redirect: https://facebook.com/TuiraDC
- - role: nginx/site
- site: foo.sh
- redirect: https://www.foo.sh/
- - role: nginx/site
- site: autoconfig.foo.sh
- - role: nginx/site
- site: boot.foo.sh
- ssl_config: old
- - role: nginx/site
- site: bitbucket.foo.sh
- redirect: https://bitbucket.org/tmakinen/
- - role: nginx/site
- site: certbot.home.foo.sh
- proxy: https://certbot.home.foo.sh/
- - role: nginx/site
- site: chat.foo.sh
- proxy:
- - https://oci-node01.home.foo.sh/rocketchat/
- - https://oci-node02.home.foo.sh/rocketchat/
- - role: nginx/site
- site: collab.foo.sh
- proxy: https://collab01.home.foo.sh/
- - role: nginx/site
- site: devel01.foo.sh
- proxy: https://devel01.home.foo.sh/
- - role: nginx/site
- site: dns.home.foo.sh
- redirect: https://www.foo.sh/
- - role: nginx/site
- site: git.foo.sh
- proxy: https://gitea02.home.foo.sh/
- - role: nginx/site
- site: gitea.foo.sh
- redirect: https://git.foo.sh/
- - role: nginx/site
- site: ha.foo.sh
- proxy: https://homeassistant01.home.foo.sh/
- - role: nginx/site
- site: id.foo.sh
- proxy:
+ - nginx
+ - nginx_logsync
+ - role: nginx_site
+ nginx_site_name: ca.foo.sh
+ - role: nginx_site
+ nginx_site_name: foo.monster
+ - role: nginx_site
+ nginx_site_name: tuiradc.fi
+ nginx_site_redirect: https://facebook.com/TuiraDC
+ - role: nginx_site
+ nginx_site_name: www.tuiradc.fi
+ nginx_site_redirect: https://facebook.com/TuiraDC
+ - role: nginx_site
+ nginx_site_name: foo.sh
+ nginx_site_redirect: https://www.foo.sh/
+ - role: nginx_site
+ nginx_site_name: apps.foo.sh
+ nginx_site_load_balance_method: ip_hash
+ nginx_site_proxy:
- https://oci-node01.home.foo.sh
- https://oci-node02.home.foo.sh
- - role: nginx/site
- site: influxdb.foo.sh
- proxy: https://influxdb01.home.foo.sh/
- - role: nginx/site
- site: iot.foo.sh
- redirect: https://www.foo.sh/
- - role: nginx/site
- site: munin.foo.sh
- proxy: https://munin01.home.foo.sh/
- - role: nginx/site
- site: mirrors.foo.sh
- proxy: https://mirror01.home.foo.sh/
- - role: nginx/site
- site: noc.foo.sh
- proxy:
+ - role: nginx_site
+ nginx_site_name: audiobooks.foo.sh
+ nginx_site_proxy: https://audiobooks02.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: autoconfig.foo.sh
+ - role: nginx_site
+ nginx_site_name: boot.foo.sh
+ - role: nginx_site
+ nginx_site_name: bitbucket.foo.sh
+ nginx_site_redirect: https://bitbucket.org/tmakinen/
+ - role: nginx_site
+ nginx_site_name: cctv.foo.sh
+ nginx_site_proxy: https://frigate02.home.foo.sh/frigate/
+ - role: nginx_site
+ nginx_site_name: certbot.home.foo.sh
+ nginx_site_proxy: https://certbot.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: chat.foo.sh
+ nginx_site_proxy:
+ - https://oci-node01.home.foo.sh/rocketchat/
+ - https://oci-node02.home.foo.sh/rocketchat/
+ - role: nginx_site
+ nginx_site_name: collab.foo.sh
+ nginx_site_proxy: https://collab01.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: devel01.foo.sh
+ nginx_site_proxy: https://devel01.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: dns.home.foo.sh
+ nginx_site_redirect: https://www.foo.sh/
+ - role: nginx_site
+ nginx_site_name: forgejo.foo.sh
+ nginx_site_redirect: https://git.foo.sh/
+ - role: nginx_site
+ nginx_site_name: git.foo.sh
+ nginx_site_proxy: https://forgejo02.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: gitea.foo.sh
+ nginx_site_redirect: https://git.foo.sh/
+ - role: nginx_site
+ nginx_site_name: ha.foo.sh
+ nginx_site_proxy: https://homeassistant01.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: id.foo.sh
+ nginx_site_proxy:
+ - https://oci-node01.home.foo.sh
+ - https://oci-node02.home.foo.sh
+ - role: nginx_site
+ nginx_site_name: idp.foo.sh
+ nginx_site_proxy: https://oci-node01.home.foo.sh/ipsilon/
+ - role: nginx_site
+ nginx_site_name: influxdb.foo.sh
+ nginx_site_proxy: https://influxdb01.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: iot.foo.sh
+ nginx_site_redirect: https://www.foo.sh/
+ - role: nginx_site
+ nginx_site_name: mirrors.foo.sh
+ nginx_site_proxy: https://mirror02.home.foo.sh/
+ - role: nginx_site
+ nginx_site_name: movies.foo.sh
+ nginx_site_proxy:
+ - https://oci-node01.home.foo.sh/php4dvd/
+ - role: nginx_site
+ nginx_site_name: mta-sts.foo.sh
+ - role: nginx_site
+ nginx_site_name: noc.foo.sh
+ nginx_site_proxy:
- https://oci-node01.home.foo.sh/grafana/
- https://oci-node02.home.foo.sh/grafana/
- - role: nginx/site
- site: print.foo.sh
- proxy: https://print01.home.foo.sh:631/
- - role: nginx/site
- site: registry.foo.sh
- proxy: ["registry01.home.foo.sh:5000", "registry02.home.foo.sh:5000"]
- - role: nginx/site
- site: webmail.foo.sh
- proxy:
+ - role: nginx_site
+ nginx_site_name: print.foo.sh
+ nginx_site_proxy: https://print01.home.foo.sh:631/
+ - role: nginx_site
+ nginx_site_name: registry.foo.sh
+ nginx_site_proxy:
+ - "registry01.home.foo.sh:5000"
+ - "registry02.home.foo.sh:5000"
+ - role: nginx_site
+ nginx_site_name: scan.foo.sh
+ nginx_site_proxy:
+ - https://sane02.home.foo.sh/scanservjs/
+ - role: nginx_site
+ nginx_site_name: webmail.foo.sh
+ nginx_site_load_balance_method: ip_hash
+ nginx_site_proxy:
- https://oci-node01.home.foo.sh/roundcube/
- - role: nginx/site
- site: wpad.foo.sh
- - role: nginx/site
- site: www.foo.sh
- - role: nginx/site
- site: zm.foo.sh
- proxy: https://zm02.home.foo.sh/
+ - https://oci-node02.home.foo.sh/roundcube/
+ - role: nginx_site
+ nginx_site_name: wpad.foo.sh
+ - role: nginx_site
+ nginx_site_name: www.foo.sh
diff --git a/playbooks/relay.yml b/playbooks/relay.yml
index f6cd46d..0d0e8b8 100644
--- a/playbooks/relay.yml
+++ b/playbooks/relay.yml
@@ -16,13 +16,13 @@
- base
- ifstated
- relayd
- - nginx/server
- - role: nginx/site
- site: ldap.foo.sh
- redirect: https://www.foo.sh/
- - role: nginx/site
- site: ldap01.foo.sh
- redirect: https://www.foo.sh/
- - role: nginx/site
- site: loghost.foo.sh
- redirect: https://www.foo.sh/
+ - nginx
+ - role: nginx_site
+ nginx_site_name: ldap.foo.sh
+ nginx_site_redirect: https://www.foo.sh/
+ - role: nginx_site
+ nginx_site_name: ldap01.foo.sh
+ nginx_site_redirect: https://www.foo.sh/
+ - role: nginx_site
+ nginx_site_name: loghost.foo.sh
+ nginx_site_redirect: https://www.foo.sh/
diff --git a/playbooks/sane.yml b/playbooks/sane.yml
new file mode 100644
index 0000000..cb8101f
--- /dev/null
+++ b/playbooks/sane.yml
@@ -0,0 +1,39 @@
+---
+- name: Deploy KVM virtual machines
+ ansible.builtin.import_playbook: include/deploy-kvm-guest.yml
+ vars:
+ myhosts: sane
+
+- name: Configure instance
+ hosts: sane
+ user: root
+ gather_facts: true
+
+ vars_files:
+ - "{{ ansible_private }}/vars.yml"
+
+ roles:
+ - base
+ - sane
+ - scanservjs
+ - mod_auth_gssapi
+ - role: keytab
+ keytab_path: /etc/httpd/httpd.keytab
+ keytab_principals: HTTP/scan.foo.sh@FOO.SH
+ keytab_group: apache
+
+ tasks:
+ - name: Require authentication for scanservjs
+ ansible.builtin.copy:
+ dest: /etc/httpd/conf.local.d/scanservjs-auth.conf
+ content: |
+
+ AuthType GSSAPI
+ GssapiBasicAuth On
+ AuthName "Password Required"
+ Require valid-user
+
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart apache
diff --git a/playbooks/shell.yml b/playbooks/shell.yml
index d331810..9b4b060 100644
--- a/playbooks/shell.yml
+++ b/playbooks/shell.yml
@@ -15,7 +15,7 @@
roles:
- base
- role: keytab
- principals:
+ keytab_principals:
- "host/{{ inventory_hostname }}@{{ kerberos_realm }}"
- "nfs/{{ inventory_hostname }}@{{ kerberos_realm }}"
- nfs_client
@@ -24,9 +24,8 @@
- thinlinc_server
- epel_repo
- foosh_repo
- - powertools_repo
- - role: nginx/server
- plaintext: true
+ - role: nginx
+ nginx_plaintext: true
tasks:
- name: Install extra package groups
@@ -63,6 +62,7 @@
- pandoc
- php-cli
- python3-netaddr
+ - python3-requests
- rcs
- rpmlint
- syslinux
@@ -71,7 +71,6 @@
- tmux
- whois
- wireshark
- - wkhtmltopdf
- yamllint
- zsh
loop_control:
@@ -98,6 +97,6 @@
content: |
Host *.home.foo.sh !gw.home.foo.sh
ProxyJump root@gw.home.foo.sh
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/playbooks/static.yml b/playbooks/static.yml
index 25636a9..8471c0a 100644
--- a/playbooks/static.yml
+++ b/playbooks/static.yml
@@ -15,7 +15,7 @@
roles:
- base
- role: keytab
- principals:
+ keytab_principals:
- "host/{{ inventory_hostname }}@FOO.SH"
- "nfs/{{ inventory_hostname }}@FOO.SH"
- nfs_client
@@ -48,7 +48,7 @@
AllowOverride AuthConfig FileInfo Indexes Limit
Require all granted
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
diff --git a/playbooks/vmhost.yml b/playbooks/vmhost.yml
index 66a3139..3869f1c 100644
--- a/playbooks/vmhost.yml
+++ b/playbooks/vmhost.yml
@@ -17,6 +17,7 @@
passno: "0"
dump: "0"
state: mounted
+ when: inventory_hostname == "vmhost02.home.foo.sh"
- name: Mount /export/libvirt/nvme
ansible.posix.mount:
name: /export/libvirt/nvme
@@ -26,10 +27,10 @@
passno: "0"
dump: "0"
state: mounted
- - name: Mount /export/libvirt/ssd
+ - name: Mount /export/libvirt/os
ansible.posix.mount:
- name: /export/libvirt/ssd
- src: LABEL=ssd
+ name: /export/libvirt/os
+ src: LABEL=os
fstype: xfs
opts: noatime,noexec,nosuid,nodev
passno: "0"
@@ -39,3 +40,4 @@
roles:
- base
- kvm_host
+ - ssh_known_hosts
diff --git a/roles/ansible_host/files/urls.py.patch b/roles/ansible_host/files/urls.py.patch
new file mode 100644
index 0000000..ee1dda4
--- /dev/null
+++ b/roles/ansible_host/files/urls.py.patch
@@ -0,0 +1,86 @@
+--- ./urls.py.orig 2024-03-27 18:55:18.077213253 +0000
++++ urls.py 2024-03-27 18:21:07.613270952 +0000
+@@ -535,15 +535,18 @@
+ UnixHTTPSConnection = None
+ if hasattr(httplib, 'HTTPSConnection') and hasattr(urllib_request, 'HTTPSHandler'):
+ class CustomHTTPSConnection(httplib.HTTPSConnection): # type: ignore[no-redef]
+- def __init__(self, *args, **kwargs):
++ def __init__(self, client_cert=None, client_key=None, *args, **kwargs):
+ httplib.HTTPSConnection.__init__(self, *args, **kwargs)
+ self.context = None
+ if HAS_SSLCONTEXT:
+ self.context = self._context
+ elif HAS_URLLIB3_PYOPENSSLCONTEXT:
+ self.context = self._context = PyOpenSSLContext(PROTOCOL)
+- if self.context and self.cert_file:
+- self.context.load_cert_chain(self.cert_file, self.key_file)
++
++ self._client_cert = client_cert
++ self._client_key = client_key
++ if self.context and self._client_cert:
++ self.context.load_cert_chain(self._client_cert, self._client_key)
+
+ def connect(self):
+ "Connect to a host on a given (SSL) port."
+@@ -564,10 +567,10 @@
+ if HAS_SSLCONTEXT or HAS_URLLIB3_PYOPENSSLCONTEXT:
+ self.sock = self.context.wrap_socket(sock, server_hostname=server_hostname)
+ elif HAS_URLLIB3_SSL_WRAP_SOCKET:
+- self.sock = ssl_wrap_socket(sock, keyfile=self.key_file, cert_reqs=ssl.CERT_NONE, # pylint: disable=used-before-assignment
+- certfile=self.cert_file, ssl_version=PROTOCOL, server_hostname=server_hostname)
++ self.sock = ssl_wrap_socket(sock, keyfile=self._client_key, cert_reqs=ssl.CERT_NONE, # pylint: disable=used-before-assignment
++ certfile=self._client_cert, ssl_version=PROTOCOL, server_hostname=server_hostname)
+ else:
+- self.sock = ssl.wrap_socket(sock, keyfile=self.key_file, certfile=self.cert_file, ssl_version=PROTOCOL)
++ self.sock = ssl.wrap_socket(sock, keyfile=self._client_key, certfile=self._client_cert, ssl_version=PROTOCOL)
+
+ class CustomHTTPSHandler(urllib_request.HTTPSHandler): # type: ignore[no-redef]
+
+@@ -602,10 +605,6 @@
+ return self.do_open(self._build_https_connection, req)
+
+ def _build_https_connection(self, host, **kwargs):
+- kwargs.update({
+- 'cert_file': self.client_cert,
+- 'key_file': self.client_key,
+- })
+ try:
+ kwargs['context'] = self._context
+ except AttributeError:
+@@ -613,7 +612,7 @@
+ if self._unix_socket:
+ return UnixHTTPSConnection(self._unix_socket)(host, **kwargs)
+ if not HAS_SSLCONTEXT:
+- return CustomHTTPSConnection(host, **kwargs)
++ return CustomHTTPSConnection(host, client_cert=self.client_cert, client_key=self.client_key, **kwargs)
+ return httplib.HTTPSConnection(host, **kwargs)
+
+ @contextmanager
+@@ -979,7 +978,7 @@
+ pass
+
+
+-def make_context(cafile=None, cadata=None, ciphers=None, validate_certs=True):
++def make_context(cafile=None, cadata=None, ciphers=None, validate_certs=True, client_cert=None, client_key=None):
+ if ciphers is None:
+ ciphers = []
+
+@@ -1006,6 +1005,9 @@
+ if ciphers:
+ context.set_ciphers(':'.join(map(to_native, ciphers)))
+
++ if client_cert:
++ context.load_cert_chain(client_cert, keyfile=client_key)
++
+ return context
+
+
+@@ -1514,6 +1516,8 @@
+ cadata=cadata,
+ ciphers=ciphers,
+ validate_certs=validate_certs,
++ client_cert=client_cert,
++ client_key=client_key,
+ )
+ handlers.append(HTTPSClientAuthHandler(client_cert=client_cert,
+ client_key=client_key,
diff --git a/roles/ansible_host/meta/main.yml b/roles/ansible_host/meta/main.yml
index 27b9b1f..516a2dd 100644
--- a/roles/ansible_host/meta/main.yml
+++ b/roles/ansible_host/meta/main.yml
@@ -2,4 +2,4 @@
dependencies:
- {role: epel_repo}
- {role: git}
- - {role: nginx/server}
+ - {role: nginx}
diff --git a/roles/ansible_host/tasks/main.yml b/roles/ansible_host/tasks/main.yml
index 486e145..171debe 100644
--- a/roles/ansible_host/tasks/main.yml
+++ b/roles/ansible_host/tasks/main.yml
@@ -7,35 +7,22 @@
- ansible
- ansible-collection-ansible-posix
- ansible-collection-community-general
- - python3.11-dns # required for lookup('dig', 'hostname')
- - python3-netaddr # required by iptables role
+ - patch # needed in next step
+ - python3.9-dns # required for lookup('dig', 'hostname')
+ - python3.9-ldap # required for ldap modules
+ - python3.9-netaddr # required by iptables role
-- name: Create python3.11 lib directories
- ansible.builtin.file:
- path: "{{ item }}"
- state: directory
- mode: 0755
- owner: root
- group: "{{ ansible_wheel }}"
- with_items:
- - /usr/local/lib/python3.11
- - /usr/local/lib/python3.11/site-packages
-
-- name: Kludge to add netaddr to python3.11 until package is released
- ansible.builtin.copy:
- dest: /usr/local/lib/python3.11/site-packages/netaddr
- src: /usr/lib/python3.9/site-packages/netaddr
- mode: preserve
- owner: root
- group: "{{ ansible_wheel }}"
- remote_src: true
+- name: Patch ansible to support python 3.12 clients
+ ansible.posix.patch:
+ src: urls.py.patch
+ dest: /usr/lib/python3.9/site-packages/ansible/module_utils/urls.py
- name: Create private directory and force permissions
ansible.builtin.file:
path: /export/private
owner: root
group: root
- mode: 0700
+ mode: "0700"
state: directory
- name: Link private directory
@@ -55,7 +42,7 @@
- name: Clone ansible repository
ansible.builtin.git:
dest: /srv/ansible
- repo: https://git.foo.sh/ansible.git
+ repo: https://git.foo.sh/foo.sh/ansible.git
update: false
version: master
@@ -72,7 +59,7 @@
ansible.builtin.copy:
src: nginx.conf
dest: /etc/nginx/conf.d/{{ inventory_hostname }}/ansible.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
@@ -83,4 +70,4 @@
src: root-bashrc.sh
owner: root
group: "{{ ansible_wheel }}"
- mode: 0600
+ mode: "0600"
diff --git a/roles/apache/tasks/main.yml b/roles/apache/tasks/main.yml
index 0dbdd6f..c2745ed 100644
--- a/roles/apache/tasks/main.yml
+++ b/roles/apache/tasks/main.yml
@@ -40,7 +40,7 @@
ansible.builtin.file:
state: directory
path: "{{ item }}"
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
seuser: _default
@@ -54,7 +54,7 @@
ansible.builtin.template:
src: ssl.conf.j2
dest: /etc/httpd/conf.local.d/ssl.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
@@ -63,7 +63,7 @@
ansible.builtin.template:
src: site.conf.j2
dest: "/etc/httpd/conf.local.d/{{ inventory_hostname }}.conf"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
diff --git a/roles/aten_pdu/files/ATEN-PE-CFG_str_1.3.128.mib b/roles/aten_pdu/files/ATEN-PE-CFG_str_1.3.128.mib
new file mode 100644
index 0000000..d3f0ae6
--- /dev/null
+++ b/roles/aten_pdu/files/ATEN-PE-CFG_str_1.3.128.mib
@@ -0,0 +1,5065 @@
+ -- MIB version: 1.3.128
+
+ -- MIB release note
+ -- | date | MIB version | note
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 12/06/2021 | 1.3.128 | New dry contact sensor type: water leakage sensor
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 11/25/2020 | 1.3.127 | Add new OID: communityLock and passwordLock for California passes law
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 12/30/2019 | 1.3.126 | Add new OID: outletAlwaysON
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 06/22/2016 | 1.3.125 | delete OID: outletRemoteAccessLock , add OID: outletLocalAccessLock & outletSequentialReboot
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 04/28/2016 | 1.3.124 | Modify the string length in the description of outletName from 0~15 into 0~48
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 04/06/2016 | 1.3.123 | Modify minimum environmental humidity range from 15% into 10%
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 02/22/2016 | 1.3.122 | Relocate OID: outletRemoteAccessLock
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 02/03/2016 | 1.3.121 | Add new OID: outletRemoteAccessLock
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 12/29/2015 | 1.1.119 | Add new OID: smtpPort
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 07/31/2015 | 1.1.118 | Add new OID: popPriorityList
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 07/13/2015 | 1.1.117 | Add Two dry contact & hide door sensor info
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 02/11/2015 | 1.1.116 | Syntax modification of POP modes
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 12/02/2014 | 1.1.115 | Wording modification
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 10/22/2014 | 1.1.114 | Add get/set function for new POP feature
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 07/28/2014 | 1.1.113 | Modify and unify responses of empty and not-support measurement values
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 10/31/2013 | 1.1.112 | updated mib to pass smilint level 3
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 10/03/2013 | 1.1.111 | updated mib to pass smilint level 3
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 08/09/2013 | 1.1.110 | Add outlet init mode
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 07/17/2013 | 1.1.109 | Add CAP Priority Settings
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 07/05/2013 | 1.1.108 | Add Description and change some Syntax of oids
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 05/23/2013 | 1.1.107 | Change "usrEnable" order from 40 to 47 in "UsrListEntry"
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 05/21/2013 | 1.1.106 | Hide CAP function
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 05/14/2013 | 1.1.105 | Modify Power Threshold Description
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 05/07/2013 | 1.1.104 | Add CAP Function OID
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 04/26/2013 | 1.1.103 | Add Door Sensor Type OID
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 04/24/2013 | 1.1.102 | Modify Status Description of Door Sensor
+ -- --------------------------------------------------------------------------------------------------------------------------
+ -- | 02/20/2013 | 1.1.101 |
+ -- --------------------------------------------------------------------------------------------------------------------------
+
+ -- ATEN International Co., Ltd.
+ -- This file defines the mib struct of Management in PE series
+ -- We attach this mib node on enterprises.aten.atenProducts.overip.poweroverip.pe subtree
+
+
+ATEN-PE-CFG DEFINITIONS ::= BEGIN
+
+ IMPORTS
+ enterprises, IpAddress, Gauge, TimeTicks FROM RFC1155-SMI
+ enterprises FROM RFC1155-SMI
+ DisplayString FROM RFC1213-MIB
+ OBJECT-TYPE FROM RFC-1212
+ TRAP-TYPE FROM RFC-1215
+ MODULE-IDENTITY,
+ NOTIFICATION-TYPE FROM SNMPv2-SMI
+ KeyChange FROM SNMP-USER-BASED-SM-MIB
+ TEXTUAL-CONVENTION FROM SNMPv2-TC;
+
+
+
+ aten MODULE-IDENTITY
+ LAST-UPDATED "201310311110Z"
+ ORGANIZATION "ATEN"
+ CONTACT-INFO "Aten, Inc."
+ DESCRIPTION
+ "ATEN PE MIB"
+ REVISION "201310311110Z"
+ DESCRIPTION
+ "updated mib to pass smilint level 3"
+ ::= { enterprises 21317 }
+
+
+ atenProducts OBJECT IDENTIFIER ::= { aten 1 }
+ overip OBJECT IDENTIFIER ::= { atenProducts 3 }
+ poweroverip OBJECT IDENTIFIER ::= { overip 2}
+ pe OBJECT IDENTIFIER ::= {poweroverip 2}
+ userManagement OBJECT IDENTIFIER ::= { pe 1 }
+ control OBJECT IDENTIFIER ::= { pe 2 }
+ device OBJECT IDENTIFIER ::= { control 1 }
+ pop OBJECT IDENTIFIER ::= { device 17 }
+ cap OBJECT IDENTIFIER ::= { device 18 }
+ outlet OBJECT IDENTIFIER ::= { control 2 }
+ bank OBJECT IDENTIFIER ::= { control 3 }
+deviceManagement OBJECT IDENTIFIER ::= { pe 3 }
+ config OBJECT IDENTIFIER ::= { deviceManagement 4 }
+ dashBoard OBJECT IDENTIFIER ::= { config 4 }
+ servicePorts OBJECT IDENTIFIER ::= { config 5 }
+ ipv4config OBJECT IDENTIFIER ::= { config 6 }
+ eventNotification OBJECT IDENTIFIER ::= { config 7 }
+ devicesnmp OBJECT IDENTIFIER ::= { eventNotification 1 }
+ syslog OBJECT IDENTIFIER ::= { eventNotification 2 }
+ smtp OBJECT IDENTIFIER ::= { eventNotification 3 }
+ configurationNotification OBJECT IDENTIFIER ::= { eventNotification 9 }
+
+
+ dateTime OBJECT IDENTIFIER ::= { config 8 }
+ timeZone OBJECT IDENTIFIER ::= { dateTime 1 }
+ manualInput OBJECT IDENTIFIER ::= { dateTime 2 }
+ networkTime OBJECT IDENTIFIER ::= { dateTime 3 }
+
+ devicesecurity OBJECT IDENTIFIER ::= { deviceManagement 5 }
+ loginFailures OBJECT IDENTIFIER ::= { devicesecurity 1 }
+ workingMode OBJECT IDENTIFIER ::= { devicesecurity 2 }
+ accountPolicy OBJECT IDENTIFIER ::= { devicesecurity 3 }
+ loginRestriction OBJECT IDENTIFIER ::= { devicesecurity 4 }
+ ipFilter OBJECT IDENTIFIER ::= { loginRestriction 2 }
+ macFilter OBJECT IDENTIFIER ::= { loginRestriction 3 }
+ authentication OBJECT IDENTIFIER ::= { devicesecurity 5 }
+ radius OBJECT IDENTIFIER ::= { authentication 1 }
+--deviceLock OBJECT IDENTIFIER ::= { pe 4 }
+--CPM OBJECT IDENTIFIER ::= { pe 7 }
+-- CPMDevice OBJECT IDENTIFIER ::= { CPM 9 }
+-- Sensor OBJECT IDENTIFIER ::= { CPM 10 }
+-- EnergySensor OBJECT IDENTIFIER ::= { CPM 11 }
+
+
+--SNMPv3UsmAuthPrivProtocol ::= TEXTUAL-CONVENTION
+-- STATUS current
+-- DESCRIPTION
+-- "This textual convention enumerates the authentication and privledge
+-- protocol for USM configuration.
+-- "
+-- SYNTAX INTEGER
+-- {
+-- hmacMD5Auth(2),
+-- hmacSHAAuth(3)
+-- desPrivProtocol(5),
+-- aesPrivProtocol(6)
+-- }
+
+-- Device Control
+modelName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Indicate PE device model name."
+ ::= { device 1 }
+
+deviceName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The name of PE device.
+ string length: 1~39
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { device 2 }
+
+deviceValueTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF DeviceValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Device value table. This table displays device's current, voltage, power and
+ power dissipation.
+ "
+ ::= { device 3 }
+
+deviceValueEntry OBJECT-TYPE
+ SYNTAX DeviceValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single deviceValue entry containing device info."
+ INDEX { deviceValueIndex }
+ ::= { deviceValueTable 1 }
+
+DeviceValueEntry ::=
+ SEQUENCE {
+ deviceValueIndex
+ INTEGER,
+ deviceCurrent
+ DisplayString,
+ deviceVoltage
+ DisplayString,
+ devicePower
+ DisplayString,
+ devicePowerDissipation
+ DisplayString,
+ inputMaxVoltage
+ INTEGER,
+ inputMaxCurrent
+ INTEGER,
+ powerCapacity
+ INTEGER,
+ devicePowerFactor
+ DisplayString
+ }
+
+deviceValueIndex OBJECT-TYPE
+ SYNTAX INTEGER (1)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of deviceValue."
+ ::= { deviceValueEntry 1 }
+deviceCurrent OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device electric current value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { deviceValueEntry 2 }
+deviceVoltage OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device voltage value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { deviceValueEntry 3 }
+devicePower OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device power value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { deviceValueEntry 4 }
+
+devicePowerDissipation OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device power dissipation value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { deviceValueEntry 5 }
+
+inputMaxVoltage OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device input Voltage value. unit:(V)
+ If the device does not support this OID, we show value 0.
+ "
+ ::= { deviceValueEntry 6 }
+
+inputMaxCurrent OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device input Current value. unit:(A)
+ If the device does not support this OID, we show value 0."
+ ::= { deviceValueEntry 7 }
+
+powerCapacity OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device power Capacity value.unit:(VA)
+ If the device does not support this OID, we show value 0."
+ ::= { deviceValueEntry 8 }
+
+devicePowerFactor OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Device power Factor value.
+ If the device does not support this OID, it returns: not-support."
+ ::= { deviceValueEntry 9 }
+
+sensorValueTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SensorValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Device's sensor value table. This table displays sensor's temperature, humidity and
+ pressure.
+ "
+ ::= { device 4 }
+
+sensorValueEntry OBJECT-TYPE
+ SYNTAX SensorValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single device's sensor value entry containing device info."
+ INDEX { sensorValueIndex }
+ ::= { sensorValueTable 1 }
+
+SensorValueEntry ::=
+ SEQUENCE {
+ sensorValueIndex
+ INTEGER,
+ sensorTemperature
+ DisplayString,
+ sensorHumidity
+ DisplayString,
+ sensorPressure
+ DisplayString,
+ sensorProperty
+ INTEGER
+ }
+
+sensorValueIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..6)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of sensor number."
+ ::= { sensorValueEntry 1 }
+sensorTemperature OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Sensor's Temperature value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { sensorValueEntry 2 }
+sensorHumidity OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Sensor's Humidity value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { sensorValueEntry 3 }
+sensorPressure OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Sensor's Pressure value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { sensorValueEntry 4 }
+
+sensorProperty OBJECT-TYPE
+ SYNTAX INTEGER { intake(1), exhaust(2), floor(3) }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Sensor's Property."
+ ::= { sensorValueEntry 5 }
+
+deviceOutletStatusTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF DeviceOutletStatusEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Device outlet status value table."
+ ::= { device 5 }
+
+deviceOutletStatusEntry OBJECT-TYPE
+ SYNTAX DeviceOutletStatusEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single deviceOutletStatus entry containing device info."
+ INDEX { deviceOutletStatusIndex }
+ ::= { deviceOutletStatusTable 1 }
+
+DeviceOutletStatusEntry ::=
+ SEQUENCE {
+ deviceOutletStatusIndex
+ INTEGER,
+ displayOutletStatus
+ INTEGER
+
+ }
+
+deviceOutletStatusIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..30)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of deviceOutletStatus"
+ ::= { deviceOutletStatusEntry 1 }
+displayOutletStatus OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), fault(4), noauth(5), not-support(6), pop(7) }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Display outlet status."
+ ::= { deviceOutletStatusEntry 2 }
+
+
+deviceConfigTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF DeviceConfigEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Device configuration table"
+ ::= { device 6 }
+
+deviceConfigEntry OBJECT-TYPE
+ SYNTAX DeviceConfigEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single deviceConfig entry containing device info."
+ INDEX { deviceConfigIndex }
+ ::= { deviceConfigTable 1 }
+
+DeviceConfigEntry ::=
+ SEQUENCE {
+ deviceConfigIndex
+ INTEGER,
+ deviceMinCurMT
+ INTEGER,
+ deviceMaxCurMT
+ INTEGER,
+
+ deviceMinVolMT
+ INTEGER,
+ deviceMaxVolMT
+ INTEGER,
+ deviceMinPMT
+ INTEGER,
+ deviceMaxPMT
+ INTEGER,
+
+ --deviceMinPDMT
+ --INTEGER,
+ deviceMaxPDMT
+ INTEGER
+ --deviceCurFlu
+ -- INTEGER,
+ --deviceVolFlu
+ -- INTEGER,
+ --devicePFlu
+ -- INTEGER
+ --devicePDFlu
+ --INTEGER
+ }
+
+deviceConfigIndex OBJECT-TYPE
+ SYNTAX INTEGER (1)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of deviceConfig"
+ ::= { deviceConfigEntry 1 }
+deviceMinCurMT OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device minimum electric current measurement threshold.
+ Example: range 0.0~32.0 represents 0~320.
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceConfigEntry 2 }
+deviceMaxCurMT OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device maximum electric current measurement threshold.
+ Example: range 0.0~32.0 represents 0~320
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceConfigEntry 3 }
+
+deviceMinVolMT OBJECT-TYPE
+ SYNTAX INTEGER (900..2600 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device minimum voltage measurement threshold.
+ Exapmple: range 90.0~260.0 represents 900~2600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceConfigEntry 4 }
+
+deviceMaxVolMT OBJECT-TYPE
+ SYNTAX INTEGER (900..2600 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device maximum voltage measurement threshold.
+ Example: range 90.0~260.0 represents 900~2600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceConfigEntry 5 }
+
+deviceMinPMT OBJECT-TYPE
+ SYNTAX INTEGER (0..99999 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device minimum power measurement threshold.
+ Example: range 0.0 ~ 9999.9 represents 0~99999
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceConfigEntry 6 }
+
+deviceMaxPMT OBJECT-TYPE
+ SYNTAX INTEGER (0..99999 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device maximum power measurement threshold.
+ Example: range 0.0 ~ 9999.9 represents 0~99999
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceConfigEntry 7 }
+
+--deviceCurFlu OBJECT-TYPE
+ --SYNTAX INTEGER
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display device electric current fluctuation threshold.
+ -- Fluctuation Range = (MaxThreshold-MinThreshold)/2 x10
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { deviceConfigEntry 9 }
+
+--deviceVolFlu OBJECT-TYPE
+ --SYNTAX INTEGER
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display device voltage fluctuation threshold.
+ -- Fluctuation Range = (MaxThreshold-MinThreshold)/2 x10
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { deviceConfigEntry 10 }
+
+--devicePFlu OBJECT-TYPE
+ --SYNTAX INTEGER
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display device power fluctuation threshold.
+ -- Fluctuation Range = (MaxThreshold-MinThreshold)/2 x10
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { deviceConfigEntry 11 }
+
+--deviceMinPDMT OBJECT-TYPE
+ --SYNTAX INTEGER (0..2000)
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set device minimum power dissipation measurement threshold."
+ --::= { deviceConfigEntry 8 }
+deviceMaxPDMT OBJECT-TYPE
+ SYNTAX INTEGER (0..999990 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device maximum power dissipation measurement threshold.
+ Example: range 0.0 ~ 99999.0 represents 0~999990
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceConfigEntry 8 }
+--devicePDFlu OBJECT-TYPE
+ --SYNTAX INTEGER (0..2000)
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display device power dissipation fluctuation threshold."
+ --::= { deviceConfigEntry 13 }
+
+
+deviceSensorTresholdTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF DeviceSensorTresholdEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Device environment value table"
+ ::= { device 7 }
+
+deviceSensorTresholdEntry OBJECT-TYPE
+ SYNTAX DeviceSensorTresholdEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Device's sensor Environment entry containing sensor info."
+ INDEX { deviceSensorTresholdIndex }
+ ::= { deviceSensorTresholdTable 1 }
+
+DeviceSensorTresholdEntry ::=
+ SEQUENCE {
+ deviceSensorTresholdIndex
+ INTEGER,
+ sensorMinTempMT
+ INTEGER,
+ sensorMaxTempMT
+ INTEGER,
+
+ sensorMinHumMT
+ INTEGER,
+ sensorMaxHumMT
+ INTEGER,
+ sensorMinPressMT
+ INTEGER,
+ sensorMaxPressMT
+ INTEGER
+ --sensorTempFlu
+ --INTEGER,
+ --sensorHumFlu
+ --INTEGER,
+ --sensorPressFlu
+ --INTEGER
+ }
+
+deviceSensorTresholdIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..6)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of sensor number"
+ ::= { deviceSensorTresholdEntry 1 }
+
+sensorMinTempMT OBJECT-TYPE
+ SYNTAX INTEGER (-200..600 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set sensor minimum temperature measurement threshold.
+ Example: range -20.0 ~ 60.0 represents -200~600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceSensorTresholdEntry 2 }
+sensorMaxTempMT OBJECT-TYPE
+ SYNTAX INTEGER (-200..600 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set sensor maximum temperature measurement threshold.
+ Example: range -20.0 ~ 60.0 represents -200~600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceSensorTresholdEntry 3 }
+
+sensorMinHumMT OBJECT-TYPE
+ SYNTAX INTEGER (100..950 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set sensor minimum humidity measurement threshold.
+ Example: range 10.0 ~ 95.0 represents 100~950
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceSensorTresholdEntry 4 }
+sensorMaxHumMT OBJECT-TYPE
+ SYNTAX INTEGER (100..950 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set sensor maximum humidity measurement threshold.
+ Example: range 10.0 ~ 95.0 represents 100~950
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceSensorTresholdEntry 5 }
+
+sensorMinPressMT OBJECT-TYPE
+ SYNTAX INTEGER (-2500..2500 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set sensor minimum pressure measurement threshold.
+ Example: range -250.0 ~ 250.0 represents -2500 ~ 2500
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceSensorTresholdEntry 6 }
+
+sensorMaxPressMT OBJECT-TYPE
+ SYNTAX INTEGER (-2500..2500 | -3000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set sensor maximum pressure measurement threshold.
+ Example: range -250.0 ~ 250.0 represents -2500 ~ 2500
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { deviceSensorTresholdEntry 7 }
+
+--sensorTempFlu OBJECT-TYPE
+ --SYNTAX INTEGER
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display sensor temperature fluctuation threshold.
+ -- Fluctuation Range = (MaxThreshold-MinThreshold)/2 x10
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { deviceEnvironmentEntry 8 }
+
+--sensorHumFlu OBJECT-TYPE
+ --SYNTAX INTEGER
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display sensor humidity fluctuation threshold.
+ -- Fluctuation Range = (MaxThreshold-MinThreshold)/2 x10
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { deviceEnvironmentEntry 9 }
+
+
+--sensorPressFlu OBJECT-TYPE
+ --SYNTAX INTEGER
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display sensor pressure fluctuation threshold.
+ -- Fluctuation Range = (MaxThreshold-MinThreshold)/2 x10
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { deviceEnvironmentEntry 10 }
+
+deviceOutletControl OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), nostatus(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " This function is used for all outlet ports control.
+ Set off(1) to turn off for all outlet ports.
+ Set on(2) to turn on for all outlet ports.
+ Get this object always return nostatus(3), because there is no device status.
+
+ "
+ ::= { device 8 }
+
+deviceOutletReboot OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " This function is used for all outlet ports to reboot.
+ Only when outlet status is ON can do outlet reboot action to all ports.
+ Set yes(2) to reboot all outlet ports.
+ Get this object always return no(1).
+ "
+ ::= { device 9 }
+
+switchable OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2), mix(3)}
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ " Outlet is switchable or not."
+ ::= { device 10 }
+
+perportreading OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ " Outlet is per-port reading or not."
+ ::= { device 11 }
+
+sensornumber OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ " Sensor number."
+ ::= { device 12 }
+
+outletnumber OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ " Outlet number."
+ ::= { device 13 }
+
+banknumber OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ " Bank number."
+ ::= { device 14 }
+
+--chainnumber OBJECT-TYPE
+ --SYNTAX INTEGER
+ --MAX-ACCESS read-only
+ --STATUS current
+ --DESCRIPTION
+ -- " The slave device number."
+ --::= { device 15 }
+
+dryContactTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF DryContactEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Device's Dry Contact table."
+ ::= { device 15 }
+
+dryContactEntry OBJECT-TYPE
+ SYNTAX DryContactEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single device's dry contact value entry containing device info."
+ INDEX { dryContactIndex }
+ ::= { dryContactTable 1 }
+
+DryContactEntry ::=
+ SEQUENCE {
+ dryContactIndex
+ INTEGER,
+ dryContactStatus
+ INTEGER,
+ dryContactType
+ INTEGER
+ }
+
+dryContactIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..2)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of dry contact number."
+ ::= { dryContactEntry 1 }
+
+dryContactStatus OBJECT-TYPE
+ SYNTAX INTEGER { normal(0), alert(1), not-attached(2), not-support(10) }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Display dry contact status."
+ ::= { dryContactEntry 2 }
+
+dryContactType OBJECT-TYPE
+ SYNTAX INTEGER { notinstalled(0), photo(1), inductiveproximity(2), reed(3), waterleakage(4), not-support(10) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Dry contact Type Selection"
+ ::= { dryContactEntry 3 }
+
+--
+-- pop
+enablePOPmode OBJECT-TYPE
+ SYNTAX INTEGER {no(1), yes(2)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " Enable/Disable POP mode."
+ ::= { pop 1 }
+
+popThreshold OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " (-1)means default value same as Bank Max Current 16 A.
+
+ Example: range 0.0~32.0 represents 0~320
+ You can define the POP threshold or set as default(-1) value."
+ ::= { pop 2 }
+
+enableOutletPOPmode OBJECT-TYPE
+ SYNTAX INTEGER {no(1), yes(2), not-support(3)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " Enable/Disable Outlet POP mode."
+ ::= { pop 3 }
+
+enableLIFOPOPmode OBJECT-TYPE
+ SYNTAX INTEGER {no(1), yes(2), not-support(3)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " Enable/Disable LIFO POP mode."
+ ::= { pop 4 }
+
+enablePriorityPOPmode OBJECT-TYPE
+ SYNTAX INTEGER {no(1), yes(2), not-support(3)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " Enable/Disable Priority POP mode."
+ ::= { pop 5 }
+
+popPriorityList OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Indicate Outlets' power OFF priorities under Priority POP mode.
+ Outlet Separator ','
+ Bank Separator '#'
+ Assign each priority in each bank by Outlet index or zero (indicate N/A) with separators in ascendant order.
+ e.g. for model PE8324 ( Bank1: outlet 1 ~ 16, Bank2: outlet 17 ~ 24 )
+ If you want to assign priority 2, 5 of Bank 1 with Outlet 14, 3,
+ and priority 2, 6, 8 with of Bank 2 with Outlet 17, 23, 24 and left the rest with N/A,
+ please type: 0,14,0,0,3,0,0,0,0,0,0,0,0,0,0,0#0,17,0,0,0,23,0,24
+ "
+ ::= { pop 6}
+
+-- CAP
+enableCAPmode OBJECT-TYPE
+ SYNTAX INTEGER {no(1), yes(2)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " Enable/Disable CAP mode."
+ ::= { cap 1 }
+
+outletCAPTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF OutletCAPEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Outlet CAP table"
+ ::= { cap 2 }
+
+outletCAPEntry OBJECT-TYPE
+ SYNTAX OutletCAPEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Outlet CAP entry containing CAP info."
+ INDEX { outletCAPIndex }
+ ::= { outletCAPTable 1 }
+
+OutletCAPEntry ::=
+ SEQUENCE {
+ outletCAPIndex
+ INTEGER,
+ outletCAPPriority
+ INTEGER
+ }
+
+outletCAPIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..40)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of outlet's CAP configuration"
+ ::= { outletCAPEntry 1 }
+
+outletCAPPriority OBJECT-TYPE
+ SYNTAX INTEGER (0..99)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the CAP Priority of outlet.
+ Priority 0 means this outlet does not support this OID."
+ ::= { outletCAPEntry 2 }
+-- ontlet control init mode
+
+outletInitMode OBJECT-TYPE
+ SYNTAX INTEGER {no-delaytime(1), delaytime(2), not-support(3)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "choose outlet init mode you want."
+ ::= { device 19 }
+
+-- outlet sequential reboot by crystal
+outletSequentialReboot OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2), not-support(3) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " This function is used to enable or disable all outlet ports to sequential reboot.
+ "
+ ::= { device 20 }
+
+
+-- integer value
+
+--deviceIntegerValueTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF DeviceIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Device value table. This table displays device's current, voltage, power and
+-- power dissipation.
+-- "
+-- ::= { device 99 }
+
+--deviceIntegerValueEntry OBJECT-TYPE
+-- SYNTAX DeviceIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Single deviceValue entry containing device info."
+-- INDEX { deviceIntegerValueIndex }
+-- ::= { deviceIntegerValueTable 1 }
+
+--DeviceIntegerValueEntry ::=
+-- SEQUENCE {
+-- deviceIntegerValueIndex
+-- INTEGER,
+-- deviceIntegerCurrent
+-- INTEGER,
+-- deviceIntegerVoltage
+-- INTEGER,
+-- deviceIntegerPower
+-- INTEGER,
+-- deviceIntegerPowerDissipation
+-- INTEGER
+ --inputMaxVoltage
+ -- INTEGER,
+ --inputMaxCurrent
+ -- INTEGER,
+ --powerCapacity
+ -- INTEGER
+ --devicePowerFactor
+ -- INTEGER
+-- }
+
+--deviceIntegerValueIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1)
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Index of deviceValue."
+-- ::= { deviceIntegerValueEntry 1 }
+
+--deviceIntegerCurrent OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device electric current value.
+-- This value indicates that 1,000 times.
+-- "
+-- ::= { deviceIntegerValueEntry 2 }
+
+--deviceIntegerVoltage OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device voltage value.
+-- This value indicates that 1,000 times
+-- "
+-- ::= { deviceIntegerValueEntry 3 }
+
+--deviceIntegerPower OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device power value.
+-- This value indicates that 1,000 times.
+-- "
+-- ::= { deviceIntegerValueEntry 4 }
+
+--deviceIntegerPowerDissipation OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device power dissipation value.
+-- This value indicates that 1,000 times
+-- "
+-- ::= { deviceIntegerValueEntry 5 }
+
+--inputMaxVoltage OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device input Voltage value. unit:(V)"
+-- ::= { deviceValueEntry 6 }
+
+--inputMaxCurrent OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device input Current value. unit:(A)"
+-- ::= { deviceValueEntry 7 }
+
+--powerCapacity OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device power Capacity value.unit:(VA)"
+-- ::= { deviceValueEntry 8 }
+
+--devicePowerFactor OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device power Factor value."
+-- ::= { deviceValueEntry 9 }
+--
+
+--sensorIntegerValueTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF SensorIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Device's sensor value table. This table displays sensor's temperature, humidity and
+-- pressure.
+-- "
+-- ::= { device 100 }
+
+--sensorIntegerValueEntry OBJECT-TYPE
+-- SYNTAX SensorIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Single device's sensor value entry containing device info."
+-- INDEX { sensorIntegerValueIndex }
+-- ::= { sensorIntegerValueTable 1 }
+
+--SensorIntegerValueEntry ::=
+-- SEQUENCE {
+-- sensorIntegerValueIndex
+-- INTEGER,
+-- sensorIntegerTemperature
+-- INTEGER,
+-- sensorIntegerHumidity
+-- INTEGER,
+-- sensorIntegerPressure
+-- INTEGER
+ --sensorIntegerProperty
+ -- INTEGER
+-- }
+
+--sensorIntegerValueIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1..6)
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Index of sensor number."
+-- ::= { sensorIntegerValueEntry 1 }
+
+--sensorIntegerTemperature OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Sensor's Temperature value.
+-- This value indicates that 1,000 times.
+-- Value -300000 represents empty value."
+-- ::= { sensorIntegerValueEntry 2 }
+
+--sensorIntegerHumidity OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Sensor's Humidity value.
+-- This value indicates that 1,000 times.
+-- Value -300000 represents empty value."
+-- ::= { sensorIntegerValueEntry 3 }
+
+--sensorIntegerPressure OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Sensor's Pressure value.
+-- This value indicates that 1,000 times.
+-- Value -300000 represents empty value."
+-- ::= { sensorIntegerValueEntry 4 }
+
+--sensorIntegerProperty OBJECT-TYPE
+-- SYNTAX INTEGER { intake(1), exhaust(2), floor(3) }
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Sensor's Property."
+-- ::= { sensorIntegerValueEntry 5 }
+
+-- Device Control End
+
+-- Outlet Control
+outletValueTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF OutletValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Display total outlet value table"
+ ::= { outlet 1 }
+
+outletValueEntry OBJECT-TYPE
+ SYNTAX OutletValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single outletValue entry containing outlet info."
+ INDEX { outletValueIndex }
+ ::= { outletValueTable 1 }
+
+OutletValueEntry ::=
+ SEQUENCE {
+ outletValueIndex
+ INTEGER,
+ outletCurrent
+ DisplayString,
+ outletVoltage
+ DisplayString,
+ outletPower
+ DisplayString,
+ outletPowerDissipation
+ DisplayString,
+ outletMaxCurrent
+ INTEGER,
+ outletPowerFactor
+ DisplayString
+ }
+
+outletValueIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..30)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of outlet number"
+ ::= { outletValueEntry 1 }
+outletCurrent OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Outlet electric current value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { outletValueEntry 2 }
+outletVoltage OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Outlet voltage value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { outletValueEntry 3 }
+outletPower OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Outlet power value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { outletValueEntry 4 }
+outletPowerDissipation OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Outlet power dissipation value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { outletValueEntry 5 }
+
+outletMaxCurrent OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Outlet Max Current value. unit: (A).
+ If the device does not support this OID, we show value 0.
+ "
+ ::= { outletValueEntry 6 }
+
+outletPowerFactor OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Outlet Power Factor value.
+ If the device does not support this OID, it returns: not-support."
+ ::= { outletValueEntry 7 }
+
+outlet1Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 1 status. Can't set pending status."
+ ::= { outlet 2 }
+
+outlet2Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 2 status. Can't set pending status."
+ ::= { outlet 3 }
+outlet3Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 3 status. Can't set pending status."
+ ::= { outlet 4 }
+outlet4Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 4 status. Can't set pending status."
+ ::= { outlet 5 }
+outlet5Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 5 status. Can't set pending status."
+ ::= { outlet 6 }
+outlet6Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 6 status. Can't set pending status."
+ ::= { outlet 7 }
+outlet7Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 7 status. Can't set pending status."
+ ::= { outlet 8 }
+outlet8Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 8 status. Can't set pending status."
+ ::= { outlet 9 }
+
+outlet9Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 9 status. Can't set pending status."
+ ::= { outlet 11 }
+
+outlet10Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 10 status. Can't set pending status."
+ ::= { outlet 12 }
+
+outlet11Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 11 status. Can't set pending status."
+ ::= { outlet 13 }
+
+outlet12Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 12 status. Can't set pending status."
+ ::= { outlet 14 }
+
+outlet13Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 13 status. Can't set pending status."
+ ::= { outlet 15 }
+
+outlet14Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 14 status. Can't set pending status."
+ ::= { outlet 16 }
+
+outlet15Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 15 status. Can't set pending status."
+ ::= { outlet 17 }
+
+outlet16Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 16 status. Can't set pending status."
+ ::= { outlet 18 }
+
+outlet17Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 17 status. Can't set pending status."
+ ::= { outlet 19 }
+
+outlet18Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 18 status. Can't set pending status."
+ ::= { outlet 20 }
+
+outlet19Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 19 status. Can't set pending status."
+ ::= { outlet 21 }
+
+outlet20Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 20 status. Can't set pending status."
+ ::= { outlet 22 }
+
+outlet21Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 21 status. Can't set pending status."
+ ::= { outlet 23 }
+
+outlet22Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 22 status. Can't set pending status."
+ ::= { outlet 24 }
+
+outlet23Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 23 status. Can't set pending status."
+ ::= { outlet 25 }
+
+outlet24Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 24 status. Can't set pending status."
+ ::= { outlet 26 }
+
+outlet25Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 25 status. Can't set pending status."
+ ::= { outlet 27 }
+
+outlet26Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 26 status. Can't set pending status."
+ ::= { outlet 28 }
+
+outlet27Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 27 status. Can't set pending status."
+ ::= { outlet 29 }
+
+outlet28Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 28 status. Can't set pending status."
+ ::= { outlet 30 }
+
+outlet29Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 29 status. Can't set pending status."
+ ::= { outlet 31 }
+
+outlet30Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 30 status. Can't set pending status."
+ ::= { outlet 32 }
+
+outlet31Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 31 status. Can't set pending status."
+ ::= { outlet 33 }
+
+outlet32Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 32 status. Can't set pending status."
+ ::= { outlet 34 }
+
+outlet33Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 33 status. Can't set pending status."
+ ::= { outlet 35 }
+
+
+outlet34Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 34 status. Can't set pending status."
+ ::= { outlet 36 }
+
+outlet35Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 35 status. Can't set pending status."
+ ::= { outlet 37 }
+
+outlet36Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 36 status. Can't set pending status."
+ ::= { outlet 38 }
+
+outlet37Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 37 status. Can't set pending status."
+ ::= { outlet 39 }
+
+outlet38Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 38 status. Can't set pending status."
+ ::= { outlet 40 }
+
+outlet39Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 39 status. Can't set pending status."
+ ::= { outlet 41 }
+
+outlet40Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 40 status. Can't set pending status."
+ ::= { outlet 42 }
+
+outlet41Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 41 status. Can't set pending status."
+ ::= { outlet 43 }
+
+outlet42Status OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), pending(3), reboot(4), fault(5), noauth(6), not-support(7), pop(8)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display and control outlet 42 status. Can't set pending status."
+ ::= { outlet 44 }
+
+--
+
+outletSwitchableTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF OutletSwitchableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "
+ "
+ ::= { outlet 70 }
+
+outletSwitchableEntry OBJECT-TYPE
+ SYNTAX OutletSwitchableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ ""
+ INDEX { outletSwitchableIndex }
+ ::= { outletSwitchableTable 1 }
+
+ OutletSwitchableEntry ::=
+ SEQUENCE {
+ outletSwitchableIndex
+ INTEGER,
+ outletSwitchable
+ INTEGER
+
+ }
+
+outletSwitchableIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..30)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of outlet number.
+ "
+ ::= { outletSwitchableEntry 1 }
+
+outletSwitchable OBJECT-TYPE
+ SYNTAX INTEGER {no(1), yes(2) }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "
+ "
+ ::= { outletSwitchableEntry 2 }
+
+
+--outlet integer value
+
+--outletIntegerValueTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF OutletIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Display total outlet value table"
+-- ::= { outlet 99 }
+
+--outletIntegerValueEntry OBJECT-TYPE
+-- SYNTAX OutletIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Single outletValue entry containing outlet info."
+-- INDEX { outletIntegerValueIndex }
+-- ::= { outletIntegerValueTable 1 }
+
+--OutletIntegerValueEntry ::=
+-- SEQUENCE {
+-- outletIntegerValueIndex
+-- INTEGER,
+-- outletIntegerCurrent
+-- INTEGER,
+-- outletIntegerVoltage
+-- INTEGER,
+-- outletIntegerPower
+-- INTEGER,
+-- outletIntegerPowerDissipation
+-- INTEGER
+-- }
+
+--outletIntegerValueIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1..30)
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Index of outlet number.
+-- "
+-- ::= { outletIntegerValueEntry 1 }
+
+--outletIntegerCurrent OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Outlet electric current value.
+-- This value indicates that 1,000 times.
+-- "
+-- ::= { outletIntegerValueEntry 2 }
+
+--outletIntegerVoltage OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Outlet voltage value.
+-- This value indicates that 1,000 times.
+-- "
+-- ::= { outletIntegerValueEntry 3 }
+
+--outletIntegerPower OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Outlet power value.
+-- This value indicates that 1,000 times."
+-- ::= { outletIntegerValueEntry 4 }
+
+--outletIntegerPowerDissipation OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Outlet power dissipation value.
+-- This value indicates that 1,000 times."
+-- ::= { outletIntegerValueEntry 5 }
+
+
+
+
+
+outletConfigTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF OutletConfigEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Outlet configuration table"
+ ::= { outlet 10 }
+
+outletConfigEntry OBJECT-TYPE
+ SYNTAX OutletConfigEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Outlet Config entry containing outlet info."
+ INDEX { outletConfigIndex }
+ ::= { outletConfigTable 1 }
+
+OutletConfigEntry ::=
+ SEQUENCE {
+ outletConfigIndex
+ INTEGER,
+ outletName
+ DisplayString,
+ outletConfirmation
+ INTEGER,
+ outletOnDelayTime
+ INTEGER,
+ outletOffDelayTime
+ INTEGER,
+ outletShutdownMethod
+ INTEGER,
+ outletMAC
+ DisplayString,
+ outletMinCurMT
+ INTEGER,
+ outletMaxCurMT
+ INTEGER,
+ outletMinVolMT
+ INTEGER,
+ outletMaxVolMT
+ INTEGER,
+ outletMinPMT
+ INTEGER,
+ outletMaxPMT
+ INTEGER,
+ outletMaxPDMT
+ INTEGER,
+ outletLocalAccessLock
+ INTEGER
+-- outletAlwaysON
+-- INTEGER
+ }
+
+outletConfigIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..30)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of outlet number"
+ ::= { outletConfigEntry 1 }
+outletName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the name of outlet.
+ If the device does not support this OID, we show n/a.
+ string length: 0~48
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { outletConfigEntry 2 }
+outletConfirmation OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) , noauth(3), not-support(4)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the confirmation of outlet."
+ ::= { outletConfigEntry 3 }
+outletOnDelayTime OBJECT-TYPE
+ SYNTAX INTEGER (0..999 | -1)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the ON delay time of outlet.
+ When this model does not support the OID, we show value -1. "
+ ::= { outletConfigEntry 4 }
+outletOffDelayTime OBJECT-TYPE
+ SYNTAX INTEGER (0..999 | -1)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the OFF delay time of outlet.
+ When this model does not support the OID, we show value -1. "
+ ::= { outletConfigEntry 5 }
+outletShutdownMethod OBJECT-TYPE
+ SYNTAX INTEGER { kill-the-power(1), wake-on-lan(2), after-ac-back(3), not-support(4)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the shutdown mehtod of outlet."
+ ::= { outletConfigEntry 6 }
+outletMAC OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the MAC address of ShutdownMethod.
+ If the device does not support this OID, we show n/a.
+ string length: 12
+ "
+ ::= { outletConfigEntry 7 }
+outletMinCurMT OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet minimum electric current measurment threshold.
+ Example: range 0.0 ~16.0 rerpresnts 0~160
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { outletConfigEntry 8 }
+outletMaxCurMT OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum electric current measurment threshold.
+ Example: range 0.0 ~16.0 represents 0~160
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { outletConfigEntry 9 }
+
+outletMinVolMT OBJECT-TYPE
+ SYNTAX INTEGER (900..2600 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet minimum voltage measurment threshold.
+ Example: range 90.0 ~260.0 represents 900~2600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { outletConfigEntry 10 }
+outletMaxVolMT OBJECT-TYPE
+ SYNTAX INTEGER (900..2600 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum voltage measurment threshold.
+ Example: range 90.0 ~260.0 represents 900~2600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { outletConfigEntry 11 }
+
+outletMinPMT OBJECT-TYPE
+ SYNTAX INTEGER (0..99999 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet minimum power measurment threshold.
+ Example: range 0.0 ~ 9999.9 represents 0~99999
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { outletConfigEntry 12 }
+outletMaxPMT OBJECT-TYPE
+ SYNTAX INTEGER (0..99999 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum power measurment threshold.
+ Example: range 0.0 ~ 9999.9 represents 0~99999
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { outletConfigEntry 13 }
+
+outletMaxPDMT OBJECT-TYPE
+ SYNTAX INTEGER (0..999990 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum power dissipation measurment threshold.
+ Example: range 0.0 ~ 99999.0 represents 0~999990
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { outletConfigEntry 14 }
+
+outletLocalAccessLock OBJECT-TYPE
+ SYNTAX INTEGER {unlocked(1), locked(2), not-support(3)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Whether local access of Outlet is locked by remote or not."
+ ::= { outletConfigEntry 15}
+
+--outletAlwaysON OBJECT-TYPE
+-- SYNTAX INTEGER {no(1), yes(2), not-support(3)}
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Whether the outlet is always ON or not."
+-- ::= { outletConfigEntry 16 }
+
+-- Outlet Control End
+-- Bank control
+breakerStatusTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF BreakerStatusEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Display total bank value table"
+ ::= { bank 1 }
+
+breakerStatusEntry OBJECT-TYPE
+ SYNTAX BreakerStatusEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single bankValue entry containing bank info."
+ INDEX { breakerStatusIndex }
+ ::= { breakerStatusTable 1 }
+
+BreakerStatusEntry ::=
+ SEQUENCE {
+ breakerStatusIndex
+ INTEGER,
+ breakerStatus
+ INTEGER
+ }
+
+breakerStatusIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..30)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of breaker number."
+ ::= { breakerStatusEntry 1 }
+
+breakerStatus OBJECT-TYPE
+ SYNTAX INTEGER { off(1), on(2), not-support(3)}
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Breaker status."
+ ::= { breakerStatusEntry 2 }
+
+
+bankValueTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF BankValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Display total bank value table"
+ ::= { bank 2 }
+
+bankValueEntry OBJECT-TYPE
+ SYNTAX BankValueEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single bankValue entry containing bank info."
+ INDEX { bankValueIndex }
+ ::= { bankValueTable 1 }
+
+BankValueEntry ::=
+ SEQUENCE {
+ bankValueIndex
+ INTEGER,
+ bankCurrent
+ DisplayString,
+ bankVoltage
+ DisplayString,
+ bankPower
+ DisplayString,
+ bankPowerDissipation
+ DisplayString,
+ bankMaxCurrent
+ INTEGER,
+ bankAttachStatus
+ INTEGER,
+ bankPowerFactor
+ DisplayString
+ }
+
+bankValueIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..30)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of bank number"
+ ::= { bankValueEntry 1 }
+bankCurrent OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Bank electric current value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { bankValueEntry 2 }
+bankVoltage OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Bank voltage value.
+ We put this OID to write access type for user to set the reference voltage on EC1000 model.
+ And the setting should be the numbers. You can set 0 to clear the setting.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { bankValueEntry 3 }
+
+bankPower OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Bank power value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { bankValueEntry 4 }
+
+bankPowerDissipation OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Bank power dissipation value.
+ If this measurement value is not available, it returns: N/A.
+ If the device does not support this OID, it returns: not-support."
+ ::= { bankValueEntry 5 }
+
+
+bankMaxCurrent OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The Bank Max Current value. unit: (A)
+ EC1000:0A~320A
+ "
+ ::= { bankValueEntry 6 }
+
+bankAttachStatus OBJECT-TYPE
+ SYNTAX INTEGER { noattached(1), attached(2), error(3), noexisted(4) }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The status of Energy sensor Bank attached status."
+ ::= { bankValueEntry 7 }
+
+bankPowerFactor OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Bank Power Factor value.
+ If the device does not support this OID, it returns: not-support."
+ ::= { bankValueEntry 8 }
+
+bankConfigTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF BankConfigEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Bank configuration table"
+ ::= { bank 3 }
+
+bankConfigEntry OBJECT-TYPE
+ SYNTAX BankConfigEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Bank Config entry containing Bank info."
+ INDEX { bankConfigIndex }
+ ::= { bankConfigTable 1 }
+
+BankConfigEntry ::=
+ SEQUENCE {
+ bankConfigIndex
+ INTEGER,
+ bankName
+ DisplayString,
+ bankMinCurMT
+ INTEGER,
+ bankMaxCurMT
+ INTEGER,
+
+ bankMinVolMT
+ INTEGER,
+ bankMaxVolMT
+ INTEGER,
+
+ bankMinPMT
+ INTEGER,
+ bankMaxPMT
+ INTEGER,
+ --outletMinPDMT
+ --INTEGER,
+ bankMaxPDMT
+ INTEGER
+ --outletCurFlu
+ --INTEGER,
+ --outletVolFlu
+ --INTEGER,
+ --outletPFlu
+ --INTEGER
+ --outletPDFlu
+ --INTEGER
+ }
+
+bankConfigIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..30)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of bank number"
+ ::= { bankConfigEntry 1 }
+
+bankName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the name of bank.
+ When this model does not support the OID, we show n/a.
+ string length: 0~15
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { bankConfigEntry 2 }
+
+
+bankMinCurMT OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet minimum electric current measurment threshold.
+ Example: range 0.0 ~16.0 rerpresnts 0~160
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { bankConfigEntry 3 }
+
+bankMaxCurMT OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum electric current measurment threshold.
+ Example: range 0.0 ~16.0 represents 0~160
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { bankConfigEntry 4}
+
+bankMinVolMT OBJECT-TYPE
+ SYNTAX INTEGER (900..2600 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet minimum voltage measurment threshold.
+ Example: range 90.0 ~260.0 represents 900~2600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { bankConfigEntry 5 }
+bankMaxVolMT OBJECT-TYPE
+ SYNTAX INTEGER (900..2600 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum voltage measurment threshold.
+ Example: range 90.0 ~260.0 represents 900~2600
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { bankConfigEntry 6 }
+
+bankMinPMT OBJECT-TYPE
+ SYNTAX INTEGER (0..99999| -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet minimum power measurment threshold.
+ Example: range 0.0 ~ 9999.9 represents 0~99999
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { bankConfigEntry 7 }
+bankMaxPMT OBJECT-TYPE
+ SYNTAX INTEGER (0..99999 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum power measurment threshold.
+ Example: range 0.0 ~ 9999.9 represents 0~99999
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { bankConfigEntry 8 }
+
+--outletMinPDMT OBJECT-TYPE
+ --SYNTAX INTEGER (0..100)
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the outlet minimum power dissipation measurment threshold ."
+ --::= { outletConfigEntry 14 }
+
+bankMaxPDMT OBJECT-TYPE
+ SYNTAX INTEGER (0..999990 | -3000 | -2000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the outlet maximum power dissipation measurment threshold.
+ Example: range 0.0 ~ 99999.0 represents 0~999990
+ NOTICE: Minimum threshold should be smaller than maximum threshold.
+ Empty value: -3000.
+ If the device does not support this OID, it returns value -2000000."
+ ::= { bankConfigEntry 9 }
+
+
+bankControlTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF BankControlEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Bank Control table"
+ ::= { bank 4 }
+
+bankControlEntry OBJECT-TYPE
+ SYNTAX BankControlEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Bank control entry."
+ INDEX { bankControlIndex }
+ ::= { bankControlTable 1 }
+
+BankControlEntry ::=
+ SEQUENCE {
+ bankControlIndex
+ INTEGER,
+ bankControlStatus
+ INTEGER
+ }
+
+bankControlIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..4)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of bank number"
+ ::= { bankControlEntry 1 }
+
+bankControlStatus OBJECT-TYPE
+ SYNTAX INTEGER {off(1), on(2), reboot(3), nostatus(4), not-support(5)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " This function is used for outlet control of bank.
+ Set off(1) to turn off for outlet control of bank.
+ Set on(2) to turn on for all outlet control of bank.
+ Set reboot(3) to turn on for outlet control of bank.
+ Get this object always return nostatus(3), because there is no bank status.
+ "
+ ::= { bankControlEntry 2 }
+
+-- Bank control End
+
+
+--bankIntegerValueTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF BankIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Display total bank value table"
+-- ::= { bank 99 }
+
+--bankIntegerValueEntry OBJECT-TYPE
+-- SYNTAX BankIntegerValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Single bankValue entry containing bank info."
+-- INDEX { bankIntegerValueIndex }
+-- ::= { bankIntegerValueTable 1 }
+
+--BankIntegerValueEntry ::=
+-- SEQUENCE {
+-- bankIntegerValueIndex
+-- INTEGER,
+-- bankIntegerCurrent
+-- INTEGER,
+-- bankIntegerVoltage
+-- INTEGER,
+-- bankIntegerPower
+-- INTEGER,
+-- bankIntegerPowerDissipation
+-- INTEGER
+ --bankIntegerMaxCurrent
+ -- INTEGER,
+ --bankIntegerAttachStatus
+ -- INTEGER,
+ --bankIntegerPowerFactor
+ --INTEGER
+-- }
+
+--bankIntegerValueIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1..30)
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Index of bank number.
+-- "
+-- ::= { bankIntegerValueEntry 1 }
+
+--bankIntegerCurrent OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Bank electric current value.
+-- This value indicates that 1,000 times."
+-- ::= { bankIntegerValueEntry 2 }
+--bankIntegerVoltage OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Bank voltage value.
+-- This value indicates that 1,000 times."
+-- ::= { bankIntegerValueEntry 3 }
+
+--bankIntegerPower OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Bank power value.
+-- This value indicates that 1,000 times."
+-- ::= { bankIntegerValueEntry 4 }
+
+--bankIntegerPowerDissipation OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Bank power dissipation value.
+-- This value indicates that 1,000 times."
+-- ::= { bankIntegerValueEntry 5 }
+
+
+--bankMaxCurrent OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "The Bank Max Current value. unit: (A)
+-- EC1000:0A~320A
+-- "
+-- ::= { bankValueEntry 6 }
+
+--bankAttachStatus OBJECT-TYPE
+-- SYNTAX INTEGER { noattached(1), attached(2), error(3) }
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "The status of Energy sensor Bank attached status."
+-- ::= { bankValueEntry 7 }
+
+--bankPowerFactor OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Bank Power Factor value"
+-- ::= { bankValueEntry 8 }
+
+
+
+-- Device Management
+deviceMAC OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Display device MAC address."
+ ::= { config 1 }
+
+deviceIPv4 OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Display device IP address."
+ ::= { config 2 }
+
+deviceFWversion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Display device FW version."
+ ::= { config 3 }
+
+-- dashboard settings
+dashboardRow OBJECT-TYPE
+ SYNTAX INTEGER (1..26)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device's dashboard row number."
+ ::= { dashBoard 1 }
+
+dashboardColumn OBJECT-TYPE
+ SYNTAX INTEGER (1..26)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device's dashboard column number."
+ ::= { dashBoard 2 }
+
+dashboardRackName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set device's dashboard rack name.
+ string length: 1~32
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { dashBoard 3 }
+
+httpPort OBJECT-TYPE
+ SYNTAX INTEGER (1..65535)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the HTTP port of PE device."
+ ::= { servicePorts 1 }
+
+httpsPort OBJECT-TYPE
+ SYNTAX INTEGER (1..65535)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the HTTPs port of PE device."
+ ::= { servicePorts 2 }
+
+httpsOnlyEnable OBJECT-TYPE
+ SYNTAX INTEGER {yes(1), no(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Enable to use Webpage HTTPs only or disable to use Webpage HTTP/HTTPs"
+ ::= { servicePorts 3 }
+
+
+
+staticIPEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set IPv4 address automatically or not"
+ ::= { ipv4config 1 }
+fixedIPv4 OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set fixed IPv4 address"
+ ::= { ipv4config 2 }
+subnetMask OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set subnet mask address"
+ ::= { ipv4config 3 }
+gateway OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set gateway address"
+ ::= { ipv4config 4 }
+staticDNSEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set DNS address automatically or not"
+ ::= { ipv4config 5 }
+dnsPreferIPv4 OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set prefer DNS address"
+ ::= { ipv4config 6 }
+dnsAlternateIPv4 OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set alternate DNS address"
+ ::= { ipv4config 7 }
+
+trapEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Indicates if this trap entry is enabled or not.
+ You should set the username/auth-password/priv-password first, when choosing snmpv3.
+ You should set the community string first, when choosing snmpv1/v2c."
+ ::= { devicesnmp 1 }
+
+trapVersion OBJECT-TYPE
+ SYNTAX INTEGER { v1(1), v2c(2), v3(3)}
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " Choose SNMP Trap version to send trap.
+ You should set the username/auth-password/priv-password first, when choosing snmpv3.
+ You should set the community string first, when choosing snmpv1/v2c."
+ ::= { devicesnmp 2 }
+
+snmpTrapTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SnmpTrapEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "PE SNMP agent trap setup table. If users want to use trap,
+ they must set enable trap, ip and community first."
+ ::= { devicesnmp 3 }
+
+snmpTrapEntry OBJECT-TYPE
+ SYNTAX SnmpTrapEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Single trap entry containing trap receiver info."
+ INDEX { trapReceiverNumber }
+ ::= { snmpTrapTable 1 }
+
+SnmpTrapEntry ::=
+ SEQUENCE {
+ trapReceiverNumber
+ INTEGER,
+ --trapEnabled
+ --INTEGER,
+ trapReceiverIPAddress
+ IpAddress,
+ --trapCommunity
+ --DisplayString,
+ trapPort
+ INTEGER,
+ trapCommunity
+ DisplayString,
+ trapUsername
+ DisplayString,
+ trapAuthpassword
+ DisplayString,
+ trapPrivpassword
+ DisplayString
+ }
+
+trapReceiverNumber OBJECT-TYPE
+ SYNTAX INTEGER (1..2)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index of trap receiver"
+ ::= { snmpTrapEntry 1 }
+
+
+
+trapReceiverIPAddress OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Trap receiver IP address"
+ ::= { snmpTrapEntry 2 }
+
+
+trapPort OBJECT-TYPE
+ SYNTAX INTEGER (1..65535)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "NMS trap port to be used by agent to send trap"
+ ::= { snmpTrapEntry 3 }
+
+trapCommunity OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..20))
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "If use SNMPv1/v2c to receive trap should set this Community string.
+ MAX string length: 20
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { snmpTrapEntry 4 }
+trapUsername OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..20))
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "If use SNMPv3 to receive trap should set this string.
+ NOTE: Input string as /empty to set this object to NULL.
+ MAX string length: 20
+ "
+ ::= { snmpTrapEntry 5 }
+trapAuthpassword OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (8..20))
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "If use SNMPv3 to receive trap should set this string.
+ MAX string length: 20
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { snmpTrapEntry 6 }
+trapPrivpassword OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (8..20))
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "If use SNMPv3 to receive trap should set this string.
+ MAX string length: 20
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { snmpTrapEntry 7 }
+
+
+--privacypassword OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "SNMPv3 privacy password to be used by agent to send trap
+-- string length: 8~20
+-- "
+-- ::= { devicesnmp 4 }
+
+--engineID OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "EngineID"
+-- ::= { devicesnmp 5 }
+--engineBoot OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "EngineBoot"
+-- ::= { devicesnmp 6 }
+--engineTime OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "EngineTime"
+-- ::= { devicesnmp 7 }
+--engineMaxMSG OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "EngineMaxMSG"
+-- ::= { devicesnmp 8 }
+sysLogServerEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set syslog server address automatically or not"
+ ::= { syslog 1 }
+sysLogServerIPv4 OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set syslog server address"
+ ::= { syslog 2 }
+sysLogServerPort OBJECT-TYPE
+ SYNTAX INTEGER (1..65535)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set syslog server port"
+ ::= { syslog 3 }
+
+smtpServerEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set SMTP server enable status."
+ ::= { smtp 1 }
+smtpServerName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set a SMTP server name.
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { smtp 2 }
+smtpAuthEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set authentication of SMTP server."
+ ::= { smtp 3 }
+smtpAccountName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set a user's name of SMTP server.
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { smtp 4 }
+smtpAccountPwd OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set a user's password of SMTP server.
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { smtp 5 }
+smtpMailFrom OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set a mail of SMTP server.
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { smtp 6 }
+smtpMailTo OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set a mail of SMTP server.
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { smtp 7 }
+smtpPort OBJECT-TYPE
+ SYNTAX INTEGER (1..65535)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set SMTP server port"
+ ::= { smtp 8 }
+
+--
+
+configurationNotifyEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ " "
+ ::= { configurationNotification 1 }
+
+configurationNotifyTrapMSG NOTIFICATION-TYPE
+ STATUS current
+ --OBJECTS { customTrapMSG }
+ DESCRIPTION " "
+ ::= { configurationNotification 2 }
+
+
+--
+timeZoneSetting OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set the time zone of PE device.
+ (0) [GMT-12:00] Eniwetok Kwajalein
+ (1) [GMT-11:00] Midway Island Samoa
+ (2) [GMT-10:00] Hawaii
+ (3) [GMT-09:00] Alaska
+ (4) [GMT-08:00] Pacific Time (US & Canada); Tijuana
+ (5) [GMT-07:00] Mountain Time (US & Canada)
+ (6) [GMT-07:00] Arizona
+ (7) [GMT-06:00] Central Time (US & Canada)
+ (8) [GMT-06:00] Mexico City
+ (9) [GMT-06:00] Saskatchewan
+ (10)[GMT-06:00] Central America
+ (11)[GMT-05:00] Eastern Time (US & Canada)
+ (12)[GMT-05:00] Indiana (East)
+ (13)[GMT-05:00] Bogota Lima Quito
+ (14)[GMT-04:00] Atlantic Time (Canada)
+ (15)[GMT-04:00] Caracas La Paz
+ (16)[GMT-04:00] Santiago
+ (17)[GMT-03:30] Newfoundland
+ (18)[GMT-03:00] Buenos Aires Georgetown
+ (19)[GMT-03:00] Brasilia
+ (20)[GMT-03:00] Greenland
+ (21)[GMT-02:00] Mid-Atlantic
+ (22)[GMT-01:00] Azores
+ (23)[GMT-01:00] Cape Verde Is
+ (24)[GMT] Casablanca Monrovia
+ (25)[GMT] Greenwich Mean Time: Dublin Edinburgh Lisbon London
+ (26)[GMT+01:00] Amsterdam Copenhagen Madrid Paris Vilnius
+ (27)[GMT+01:00] West Central Africa
+ (28)[GMT+01:00] Belgrade Sarajevo Skopje Sofija Zagreb
+ (29)[GMT+01:00] Bratislava Budapest Ljubljana Prague Warsaw
+ (30)[GMT+01:00] Brussels Berlin Bern Rome Stockholm Vienna
+ (31)[GMT+02:00] Cairo
+ (32)[GMT+02:00] Harare Pretoria
+ (33)[GMT+02:00] Jerusalem
+ (34)[GMT+02:00] Bucharest
+ (35)[GMT+02:00] Helsinki Riga Tallinn
+ (36)[GMT+02:00] Athens Istanbul Minsk
+ (37)[GMT+03:00] Kuwait Riyadh
+ (38)[GMT+03:00] Nairobi
+ (39)[GMT+03:00] Baghdad
+ (40)[GMT+03:00] Moscow St. Petersburg Volgograd
+ (41)[GMT+03:30] Tehran
+ (42)[GMT+04:00] Abu Dhabi Muscat
+ (43)[GMT+04:00] Baku Tbilisi Yerevan
+ (44)[GMT+04:30] Kabul
+ (45)[GMT+05:00] Islamabad Karachi Tashkent
+ (46)[GMT+05:00] Ekaterinburg
+ (47)[GMT+05:30] Calcutta Chennai Mumbai New Delhi
+ (48)[GMT+05:45] Kathmandu
+ (49)[GMT+06:00] Astana Dhaka
+ (50)[GMT+06:00] Sri Jayawardenepura
+ (51)[GMT+06:00] Almaty Novosibirsk
+ (52)[GMT+06:30] Rangoon
+ (53)[GMT+07:00] Bangkok Hanoi Jakarta
+ (54)[GMT+07:00] Krasnoyarsk
+ (55)[GMT+08:00] Beijing Chongqing Hong Kong Urumqi
+ (56)[GMT+08:00] Perth
+ (57)[GMT+08:00] Kuala Lumpur Singapore
+ (58)[GMT+08:00] Taipei
+ (59)[GMT+08:00] Irkutsk Ulaan Bataar
+ (60)[GMT+09:00] Osaka Sapporo Tokyo
+ (61)[GMT+09:00] Seoul
+ (62)[GMT+09:00] Yakutsk
+ (63)[GMT+09:30] Darwin
+ (64)[GMT+09:30] Adelaide
+ (65)[GMT+10:00] Canberra Melbourne Sydney
+ (66)[GMT+10:00] Brisbane
+ (67)[GMT+10:00] Guam Port Moresby
+ (68)[GMT+10:00] Hobart
+ (69)[GMT+10:00] Vladivostok
+ (70)[GMT+11:00] Magadan Solomon Is New Caledonia
+ (71)[GMT+12:00] Fiji Kamchatka Marshall Is.
+ (72)[GMT+12:00] Auckland Wellington
+ (73)[GMT+13:00] Nuku'alofa
+ "
+ ::= { timeZone 1 }
+
+dstEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set daylight savings time ."
+ ::= { timeZone 2 }
+
+dateSetting OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set date in a manual way.(This is Greenwich Mean Time, GMT)
+ string length: 10
+ This value format must match the following form:
+ YYYY-MM-DD
+ ex. 2011-01-01
+ Note: range of year: 2000-2099
+ range of month: 01-12
+ range of day: 01-31
+ "
+ ::= { manualInput 1 }
+
+timeSetting OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set time in a manual way.(This is Greenwich Mean Time, GMT)
+ string length: 8
+ This value format must match the following form:
+ HH:MM:SS
+ ex. 02:02:02
+ Note: range of hour: 00-24
+ range of minute: 00-60
+ range of second: 00-60
+
+ "
+ ::= { manualInput 2 }
+
+--syncWithPC OBJECT-TYPE
+-- SYNTAX INTEGER { no(1), yes(2) }
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set date time useing sync PC way."
+-- ::= { manualInput 3 }
+
+autoAdjustEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set date time useing auto adjustment way."
+ ::= { networkTime 1 }
+
+preferNTP OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set prefer NTP server.
+ AU | ntp1.cs.mu.OZ.AU(0),
+ AU | ntp0.cs.mu.OZ.AU(1),
+ BE | ntp2.oma.be(2),
+ BE | ntp1.oma.be(3),
+ BR | ntps1.pads.ufrj.br(4),
+ CH | swisstime.ethz.ch(5),
+ CL | ntp.shoa.cl(6),
+ CZ | ntp.nic.cz(7),
+ DE | ntp.stairweb.de(8),
+ DE | ntps1-0.cs.tu-berlin.de(9),
+ DE | ptbtime1.ptb.de(10),
+ DE | ntp1.fau.de(11),
+ DE | ptbtime2.ptb.de(12),
+ DE | time1.one4vision.de(13),
+ DE | rustime01.rus.uni-stuttgart.de(14),
+ DE | ntp.probe-networks.de(15),
+ DE | ntp2.fau.de(16),
+ ES | hora.roa.es(17),
+ HK | stdtime.gov.hk(18),
+ IE | ntp-galway.hea.net(19),
+ IT | ntp1.inrim.it(20),
+ IT | ntp2.inrim.it(21),
+ JP | clock.tl.fukuoka-u.ac.jp(22),
+ JP | ntp.nict.jp(23),
+ JP | clock.nc.fukuoka-u.ac.jp(24),
+ KR | ntp.xbsd.kr(25),
+ MX | cronos.cenam.mx(26),
+ NL | ntp0.nl.uu.net(27),
+ NL | ntp1.nl.uu.net(28),
+ NL | ntp.remco.org(29),
+ NL | ntp0.nl.net(30),
+ PL | vega.cbk.poznan.pl(31),
+ PL | ntp.ntp-servers.com(32),
+ RO | ntp3.usv.ro(33),
+ RO | ntp2.usv.ro(34),
+ RU | ntp1.vniiftri.ru; ntp1.imvp.ru(35),
+ RU | ntp2.vniiftri.ru; ntp2.imvp.ru(36),
+ SE | ntp1.mmo.netnod.se(37),
+ SE | ntp1.sth.netnod.se(38),
+ SE | ntp2.mmo.netnod.se(39),
+ SE | ntp2.sth.netnod.se(40),
+ SE | time2.stupi.se(41),
+ SE | ntp1.sp.se(42),
+ SE | timehost.lysator.liu.se(43),
+ SI | ntp.mostovna.com(44),
+ US CA | timekeeper.isi.edu(45),
+ US CA | clock.sjc.he.net(46),
+ US CA | nist1.symmetricom.com(47),
+ US CA | clock.via.net(48),
+ US CA | nist1.aol-ca.truetime.com(49),
+ US CA | clock.isc.org(50),
+ US CA | clepsydra.dec.com(51),
+ US CA | gps.layer42.net(52),
+ US CA | time.no-such-agency.net(53),
+ US CA | nist1-sj.WiTime.net(54),
+ US CA | clock.fmt.he.net(55),
+ US CO | time-b.timefreq.bldrdoc.gov(56),
+ US CO | time-a.timefreq.bldrdoc.gov(57),
+ US CO | utcnist.colorado.edu(58),
+ US CO | time-c.timefreq.bldrdoc.gov(59),
+ US DE | rackety.udel.edu(60),
+ US DE | mizbeaver.udel.edu(61),
+ US GA | nist1.columbiacountyga.gov(62),
+ US IL | ntp.your.org(63),
+ US MA | bonehed.lcs.mit.edu(64),
+ US MA | time.keneli.org(65),
+ US MA | ntp0.broad.mit.edu(66),
+ US MD | time-a.nist.gov(67),
+ US MD | time-b.nist.gov(68),
+ US MI | nist.netservicesgroup.com(69),
+ US NY | nist1-ny.WiTime.net(70),
+ US NY | clock.nyc.he.net(71),
+ US UT | time.xmission.com(72),
+ US VA | nist1-dc.WiTime.net(73),
+ US VA | nist1.aol-va.truetime.com(74),
+ US WA | time-nw.nist.gov(75),
+ FR | utp.univ-lyon1.fr(76),
+ FR | ntp-sop.inria.fr(77),
+ FR | ntp.tuxfamily.net(78),
+ UK | bear.zoo.bt.co.uk(79)
+ "
+ ::= { networkTime 2 }
+
+preferServerIPenable OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Enable or disable prefer custom server IP."
+ ::= { networkTime 3 }
+
+preferNTPIp OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set prefer NTP server IP."
+ ::= { networkTime 4 }
+
+alternateNtpEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set date time using alternate NTP server."
+ ::= { networkTime 5 }
+
+alternateNtp OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set alternative NTP server.
+ AU | ntp1.cs.mu.OZ.AU(0),
+ AU | ntp0.cs.mu.OZ.AU(1),
+ BE | ntp2.oma.be(2),
+ BE | ntp1.oma.be(3),
+ BR | ntps1.pads.ufrj.br(4),
+ CH | swisstime.ethz.ch(5),
+ CL | ntp.shoa.cl(6),
+ CZ | ntp.nic.cz(7),
+ DE | ntp.stairweb.de(8),
+ DE | ntps1-0.cs.tu-berlin.de(9),
+ DE | ptbtime1.ptb.de(10),
+ DE | ntp1.fau.de(11),
+ DE | ptbtime2.ptb.de(12),
+ DE | time1.one4vision.de(13),
+ DE | rustime01.rus.uni-stuttgart.de(14),
+ DE | ntp.probe-networks.de(15),
+ DE | ntp2.fau.de(16),
+ ES | hora.roa.es(17),
+ HK | stdtime.gov.hk(18),
+ IE | ntp-galway.hea.net(19),
+ IT | ntp1.inrim.it(20),
+ IT | ntp2.inrim.it(21),
+ JP | clock.tl.fukuoka-u.ac.jp(22),
+ JP | ntp.nict.jp(23),
+ JP | clock.nc.fukuoka-u.ac.jp(24),
+ KR | ntp.xbsd.kr(25),
+ MX | cronos.cenam.mx(26),
+ NL | ntp0.nl.uu.net(27),
+ NL | ntp1.nl.uu.net(28),
+ NL | ntp.remco.org(29),
+ NL | ntp0.nl.net(30),
+ PL | vega.cbk.poznan.pl(31),
+ PL | ntp.ntp-servers.com(32),
+ RO | ntp3.usv.ro(33),
+ RO | ntp2.usv.ro(34),
+ RU | ntp1.vniiftri.ru; ntp1.imvp.ru(35),
+ RU | ntp2.vniiftri.ru; ntp2.imvp.ru(36),
+ SE | ntp1.mmo.netnod.se(37),
+ SE | ntp1.sth.netnod.se(38),
+ SE | ntp2.mmo.netnod.se(39),
+ SE | ntp2.sth.netnod.se(40),
+ SE | time2.stupi.se(41),
+ SE | ntp1.sp.se(42),
+ SE | timehost.lysator.liu.se(43),
+ SI | ntp.mostovna.com(44),
+ US CA | timekeeper.isi.edu(45),
+ US CA | clock.sjc.he.net(46),
+ US CA | nist1.symmetricom.com(47),
+ US CA | clock.via.net(48),
+ US CA | nist1.aol-ca.truetime.com(49),
+ US CA | clock.isc.org(50),
+ US CA | clepsydra.dec.com(51),
+ US CA | gps.layer42.net(52),
+ US CA | time.no-such-agency.net(53),
+ US CA | nist1-sj.WiTime.net(54),
+ US CA | clock.fmt.he.net(55),
+ US CO | time-b.timefreq.bldrdoc.gov(56),
+ US CO | time-a.timefreq.bldrdoc.gov(57),
+ US CO | utcnist.colorado.edu(58),
+ US CO | time-c.timefreq.bldrdoc.gov(59),
+ US DE | rackety.udel.edu(60),
+ US DE | mizbeaver.udel.edu(61),
+ US GA | nist1.columbiacountyga.gov(62),
+ US IL | ntp.your.org(63),
+ US MA | bonehed.lcs.mit.edu(64),
+ US MA | time.keneli.org(65),
+ US MA | ntp0.broad.mit.edu(66),
+ US MD | time-a.nist.gov(67),
+ US MD | time-b.nist.gov(68),
+ US MI | nist.netservicesgroup.com(69),
+ US NY | nist1-ny.WiTime.net(70),
+ US NY | clock.nyc.he.net(71),
+ US UT | time.xmission.com(72),
+ US VA | nist1-dc.WiTime.net(73),
+ US VA | nist1.aol-va.truetime.com(74),
+ US WA | time-nw.nist.gov(75),
+ FR | utp.univ-lyon1.fr(76),
+ FR | ntp-sop.inria.fr(77),
+ FR | ntp.tuxfamily.net(78),
+ UK | bear.zoo.bt.co.uk(79)
+ "
+ ::= { networkTime 6 }
+
+alternateServerIPenable OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Enable or disable alternate custom server IP."
+ ::= { networkTime 7 }
+
+alternateNtpIp OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set alternative NTP server IP."
+ ::= { networkTime 8 }
+
+adjustTimeEveryDays OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set frequency of adjustment in days."
+ ::= { networkTime 9 }
+
+--adjustTimeNow OBJECT-TYPE
+ --SYNTAX INTEGER { no(1), yes(2) }
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Adjust time using NTP server."
+ --::= { networkTime 8 }
+
+loginAllowTimes OBJECT-TYPE
+ SYNTAX INTEGER (1..99)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set time of login faliure."
+ ::= { loginFailures 1 }
+
+loginTimeOut OBJECT-TYPE
+ SYNTAX INTEGER (1..240)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set login time out."
+ ::= { loginFailures 2 }
+
+icmpEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set status of ICMP."
+ ::= { workingMode 1 }
+
+--multiUserEnabled OBJECT-TYPE
+ --SYNTAX INTEGER { no(1), yes(2) }
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set status of multi-user operation."
+ --::= { workingMode 2 }
+
+--browserEnabled OBJECT-TYPE
+ --SYNTAX INTEGER { no(1), yes(2) }
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set status of browser."
+ --::= { workingMode 3 }
+
+minUserNameLen OBJECT-TYPE
+ SYNTAX INTEGER (1..16)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set minimum length of user name."
+ ::= { accountPolicy 1 }
+
+minUserPwdLen OBJECT-TYPE
+ SYNTAX INTEGER (1..16)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set minimum length of user password.
+ "
+ ::= { accountPolicy 2 }
+
+upperCaseEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set one upper case rule in user password."
+ ::= { accountPolicy 3 }
+
+lowerCaseEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set one lower case rule in user password."
+ ::= { accountPolicy 4 }
+
+numberEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set one number rule in user password."
+ ::= { accountPolicy 5 }
+
+disableDuplicateLogin OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set status of disabled duplicate login rule."
+ ::= { accountPolicy 6 }
+
+loginString OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set a login string.
+ string length: 0~32
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { loginRestriction 1 }
+
+ipFilterEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set status of ip filter."
+ ::= { ipFilter 1 }
+
+ipFilterRule OBJECT-TYPE
+ SYNTAX INTEGER { include(1), exclude(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set status of ip filter rule."
+ ::= { ipFilter 2 }
+
+ipFilterTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF IpFilterEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A list of restricted ip."
+ ::= { ipFilter 3 }
+
+ipFilterEntry OBJECT-TYPE
+ SYNTAX IpFilterEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Status and parameter values for a PE's restricted IP."
+ INDEX { ipFilterIndex }
+ ::= { ipFilterTable 1 }
+
+IpFilterEntry ::=
+ SEQUENCE {
+ ipFilterIndex
+ INTEGER,
+ ipFilterFrom
+ IpAddress,
+ ipFilterTo
+ IpAddress
+ }
+
+ipFilterIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..5)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of index for the ip filter.
+ "
+ ::= { ipFilterEntry 1 }
+
+ipFilterFrom OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "A set of restricted ip.
+ ex. 192.168.0.1
+
+ Note: Users must follow in order to set the ip address.
+ Note: To clear the settings to set the ip 0.0.0.0
+ "
+ ::= { ipFilterEntry 2 }
+
+ipFilterTo OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "A set of restricted ip.
+ ex. 192.168.0.255
+
+ Note: Users must follow in order to set the ip address.
+ Note: To clear the settings to set the ip 0.0.0.0
+ "
+ ::= { ipFilterEntry 3 }
+
+macFilterEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set status of mac filter."
+ ::= { macFilter 1 }
+
+macFilterRule OBJECT-TYPE
+ SYNTAX INTEGER { include(1), exclude(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set status of mac filter rule."
+ ::= { macFilter 2 }
+
+macFilterTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MacFilterEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A list of restricted mac."
+ ::= { macFilter 3 }
+
+macFilterEntry OBJECT-TYPE
+ SYNTAX MacFilterEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Status and parameter values for a PE's restricted MAC."
+ INDEX { macFilterIndex }
+ ::= { macFilterTable 1 }
+
+MacFilterEntry ::=
+ SEQUENCE {
+ macFilterIndex
+ INTEGER,
+ macFilterSet
+ DisplayString
+ }
+
+macFilterIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..5)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of index for the mac filter.
+ "
+ ::= { macFilterEntry 1 }
+
+macFilterSet OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "A set of restricted mac.
+ string length: 12
+ ex. 004854655511
+
+ Note: Users must follow in order to set the MAC address.
+ Note: To clear the settings to set the MAC 000000000000
+ "
+ ::= { macFilterEntry 2 }
+
+--LocalAuth OBJECT-TYPE
+ --SYNTAX INTEGER { no(1), yes(2) }
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set status of disable local authentication."
+ --::= { authentication 1 }
+
+radiusEnabled OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set status of RADIUS server."
+ ::= { radius 1 }
+
+preferRadiusIp OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set prefer RADIUS server IP."
+ ::= { radius 2 }
+
+preferRadiusPort OBJECT-TYPE
+ SYNTAX INTEGER (1..65535)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set prefer RADIUS server port."
+ ::= { radius 3 }
+
+alternateRadiusIp OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set alternative RADIUS server IP."
+ ::= { radius 4 }
+
+alternateRadiusPort OBJECT-TYPE
+ SYNTAX INTEGER (1..65535)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set alternative RADIUS server port."
+ ::= { radius 5 }
+
+radiusTimeOut OBJECT-TYPE
+ SYNTAX INTEGER (1..60)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set time out of authentication using RADIUS server.
+ The unit is sec.
+ "
+ ::= { radius 6 }
+
+radiusRetry OBJECT-TYPE
+ SYNTAX INTEGER (0..10)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set retry times of authentication using RADIUS server."
+ ::= { radius 7 }
+
+radiusSecret OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set shared secret of RADIUS server.
+ string length: 6~15
+ At least 6 characters.
+ NOTE: Input string as /empty to set this object to NULL.
+ "
+ ::= { radius 8 }
+
+-- Device Management End
+
+-- User Management
+usrListTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF UsrListEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A list of user. The number of user is
+ given by the value of usrcfgNumber."
+ ::= { userManagement 1 }
+
+usrListEntry OBJECT-TYPE
+ SYNTAX UsrListEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Status and parameter values for a pe8208 user."
+ INDEX { usrIndex }
+ ::= { usrListTable 1 }
+
+UsrListEntry ::=
+ SEQUENCE {
+ usrIndex
+ INTEGER,
+ usrType
+ INTEGER,
+ usrName
+ DisplayString,
+ usrPassword
+ DisplayString,
+ usrPort1Auth
+ INTEGER,
+ usrPort2Auth
+ INTEGER,
+ usrPort3Auth
+ INTEGER,
+ usrPort4Auth
+ INTEGER,
+ usrPort5Auth
+ INTEGER,
+ usrPort6Auth
+ INTEGER,
+ usrPort7Auth
+ INTEGER,
+ usrPort8Auth
+ INTEGER,
+
+ usrPort9Auth
+ INTEGER,
+ usrPort10Auth
+ INTEGER,
+ usrPort11Auth
+ INTEGER,
+ usrPort12Auth
+ INTEGER,
+ usrPort13Auth
+ INTEGER,
+ usrPort14Auth
+ INTEGER,
+ usrPort15Auth
+ INTEGER,
+ usrPort16Auth
+ INTEGER,
+ usrPort17Auth
+ INTEGER,
+ usrPort18Auth
+ INTEGER,
+ usrPort19Auth
+ INTEGER,
+ usrPort20Auth
+ INTEGER,
+ usrPort21Auth
+ INTEGER,
+ usrPort22Auth
+ INTEGER,
+ usrPort23Auth
+ INTEGER,
+ usrPort24Auth
+ INTEGER,
+ usrPort25Auth
+ INTEGER,
+ usrPort26Auth
+ INTEGER,
+ usrPort27Auth
+ INTEGER,
+ usrPort28Auth
+ INTEGER,
+ usrPort29Auth
+ INTEGER,
+ usrPort30Auth
+ INTEGER,
+ usrPort31Auth
+ INTEGER,
+ usrPort32Auth
+ INTEGER,
+ usrPort33Auth
+ INTEGER,
+ usrPort34Auth
+ INTEGER,
+ usrPort35Auth
+ INTEGER,
+ usrPort36Auth
+ INTEGER,
+ usrPort37Auth
+ INTEGER,
+ usrPort38Auth
+ INTEGER,
+ usrPort39Auth
+ INTEGER,
+ usrPort40Auth
+ INTEGER,
+ usrPort41Auth
+ INTEGER,
+ usrPort42Auth
+ INTEGER,
+ usrEnable
+ INTEGER
+ }
+
+usrIndex OBJECT-TYPE
+ SYNTAX INTEGER (1..9)
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The value of usrIndex for the user. We have 1 administrator and 8 users.
+ The index 9 will be the administrator.
+ "
+ ::= { usrListEntry 1 }
+
+usrType OBJECT-TYPE
+ SYNTAX INTEGER { administrator(1), user(2)}
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The user's type."
+ ::= { usrListEntry 2 }
+
+usrName OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (1..16))
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "A textual string containing name of the user.
+ string length: 1~16
+ "
+ ::= { usrListEntry 3 }
+
+usrPassword OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (1..16))
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "A textual string containing password of the user.
+ string length: 1~16
+ "
+ ::= { usrListEntry 4 }
+
+usrPort1Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 1 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 5 }
+usrPort2Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 2 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 6 }
+usrPort3Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 3 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 7 }
+usrPort4Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 4 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 8 }
+usrPort5Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 5 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 9 }
+usrPort6Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Dispaly or set this user's outlet 6 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 10 }
+usrPort7Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 7 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 11 }
+usrPort8Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 8 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 12 }
+usrEnable OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), enable(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user is enable or not"
+ ::= { usrListEntry 47 }
+
+usrPort9Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 9 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 13 }
+
+usrPort10Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 10 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 14 }
+
+usrPort11Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 11 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 15 }
+
+usrPort12Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 12 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 16 }
+
+usrPort13Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 13 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 17 }
+
+
+usrPort14Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 14 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 18 }
+
+usrPort15Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 15 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 19 }
+
+usrPort16Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 16 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 20 }
+
+usrPort17Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 17 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 21 }
+
+usrPort18Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 18 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 22 }
+
+usrPort19Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 19 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 23 }
+
+usrPort20Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 20 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 24 }
+
+usrPort21Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 21 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 25 }
+
+usrPort22Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 22 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 26 }
+
+usrPort23Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 23 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 27 }
+
+usrPort24Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 24 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 28 }
+
+usrPort25Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 25 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 29 }
+
+usrPort26Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 26 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 30 }
+
+usrPort27Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 27 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 31 }
+usrPort28Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 28 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 32 }
+
+usrPort29Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 29 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 33 }
+
+usrPort30Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 30 authority.
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 34 }
+
+usrPort31Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 31 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 35 }
+
+usrPort32Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 32 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 36 }
+
+usrPort33Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 33 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 37 }
+
+usrPort34Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 34 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 38 }
+
+usrPort35Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 35 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 39 }
+
+usrPort36Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 36 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 40 }
+
+usrPort37Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 37 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 41 }
+
+usrPort38Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 38 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 42 }
+
+usrPort39Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 39 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 43 }
+
+usrPort40Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 40 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 44 }
+
+usrPort41Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 41 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 45 }
+
+usrPort42Auth OBJECT-TYPE
+ SYNTAX INTEGER { disable(1), view(2), modify(3), not-support(4) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Display or set this user's outlet 42 authority
+ Port in the pe of series represents outlet.
+ Port in the Energy monitor of series represents a bank or a pdu."
+ ::= { usrListEntry 46 }
+
+-- User Management End
+
+-- DeviceLock
+--communityLock OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Change SNMPV1 or SNMPV2 community for California passes law.
+-- Please follow the format as readcommunity||writecommunity"
+-- ::= { deviceLock 1 }
+
+--passwordLock OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Change SNMPV3 password for California passes law.
+-- Please follow the format as authpassword||privpassword"
+-- ::= { deviceLock 2 }
+-- DeviceLock End
+
+-- SNMPv3 USM Settings
+--snmpv3UsmUserTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF Snmpv3UsmUserEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION "This table is used to configure PE SNMPv3 USM.
+-- To get the SNMPv3 access, One need to configure security
+-- name,authentication,auth password,priv protocol and priv
+-- password.
+-- "
+-- ::= { snmp 2 }
+
+--snmpv3UsmUserEntry OBJECT-TYPE
+-- SYNTAX Snmpv3UsmUserEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION "A user configured for the User-based
+-- Security Model.
+-- "
+-- INDEX { usmIndex }
+-- ::= { snmpv3UsmUserTable 1 }
+
+--Snmpv3UsmUserEntry ::= SEQUENCE {
+-- usmIndex INTEGER,
+-- usmSecurityName SnmpAdminString,
+-- smAuthProtocol SNMPv3UsmAuthPrivProtocol,
+-- usmPrivPassword SnmpAdminString
+-- }
+
+--usmIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION "Usm configuration index. "
+-- ::= { snmpv3UsmUserEntry 1 }
+
+
+--usmSecurityName OBJECT-TYPE
+-- SYNTAX SnmpAdminString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION "A human readable string representing the user in
+-- Security Model independent format.
+
+-- The default transformation of the User-based Security
+-- Model dependent security ID to the securityName and
+-- vice versa is the identity function so that the
+-- securityName is the same as the userName.
+-- "
+-- ::= { snmpv3UsmUserEntry 2 }
+
+
+--usmKeyAlgorithm OBJECT-TYPE
+-- SYNTAX SNMPv3UsmAuthPrivProtocol
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION "
+-- If usmAuthProtocol == HMACMD5Auth , supports MD5 AuthKey and PrivKey
+-- If usmAuthProtocol == HMACSHAAuth, supports SHA AuthKey and PrivKey
+-- "
+-- ::= { snmpv3UsmUserEntry 3 }
+
+--usmPrivProtocol OBJECT-TYPE
+-- SYNTAX SNMPv3UsmAuthPrivProtocol
+-- MAX-ACCESS read-only
+ -- STATUS current
+ -- DESCRIPTION " A privacy protocol to provide encryption and decryption
+-- SNMPv3 pdu.
+ -- "
+ -- ::= { snmpv3UsmUserEntry 4 }
+
+--usmPrivPassword OBJECT-TYPE
+-- SYNTAX SnmpAdminString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION "An user's privacy password, Associated protocol
+-- and a secret key is used to establish a connection
+-- for the snmp agent and manager commnucation.
+-- "
+-- ::= { snmpv3UsmUserEntry 4 }
+
+
+-- SNMPv3 Target MIB
+
+--snmpv3TargetTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF Snmpv3TargetEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+ -- "A table of SNMP target information to be used
+ -- in the generation of SNMP trap messages."
+ -- ::= { snmp 3 }
+
+--snmpv3TargetEntry OBJECT-TYPE
+-- SYNTAX Snmpv3TargetEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "A set of SNMP target information.
+-- "
+-- INDEX { snmpv3TargetIndex }
+-- ::= { snmpv3TargetTable 1 }
+
+--Snmpv3TargetEntry ::= SEQUENCE {
+-- snmpv3TargetIndex INTEGER,
+-- snmpv3TargetMPModel SnmpMessageProcessingModel,
+-- snmpv3TargetSecurityModel SnmpSecurityModel,
+ -- snmpv3TargetSecurityName SnmpAdminString
+--}
+--snmpv3TargetIndex OBJECT-TYPE
+ -- SYNTAX INTEGER(1)
+ -- MAX-ACCESS not-accessible
+ -- STATUS current
+ -- DESCRIPTION
+ -- "The locally arbitrary, but unique identifier associated
+ -- with this snmpv3TargetEntry."
+ -- ::= { snmpv3TargetEntry 1 }
+
+--snmpv3TargetMPModel OBJECT-TYPE
+ -- SYNTAX SnmpMessageProcessingModel
+ -- MAX-ACCESS read-only
+ -- STATUS current
+ -- DESCRIPTION
+ -- "The Message Processing Model to be used when generating
+ -- SNMP messages using this entry."
+ -- ::= { snmpv3TargetEntry 2 }
+
+--snmpv3TargetSecurityModel OBJECT-TYPE
+ -- SYNTAX SnmpSecurityModel (1..2147483647)
+ -- MAX-ACCESS read-only
+ -- STATUS current
+ -- DESCRIPTION
+ -- "The Security Model to be used when generating SNMP
+ -- messages using this entry. An implementation may
+ -- choose to return an inconsistentValue error if an
+ -- attempt is made to set this variable to a value
+ -- for a security model which the implementation does
+ -- not support."
+ -- ::= { snmpv3TargetEntry 3 }
+
+--snmpv3TargetSecurityName OBJECT-TYPE
+ -- SYNTAX SnmpAdminString
+ -- MAX-ACCESS read-only
+ -- STATUS current
+ -- DESCRIPTION
+ -- "The securityName which identifies the Principal on
+ -- whose behalf SNMP messages will be generated using
+ -- this entry."
+ -- ::= { snmpv3TargetEntry 4 }
+
+--snmpv3TargetSecurityLevel OBJECT-TYPE
+ -- SYNTAX SnmpSecurityLevel
+ -- MAX-ACCESS read-only
+ -- STATUS current
+ -- DESCRIPTION
+ -- "The Level of Security to be used when generating
+ -- SNMP messages using this entry."
+ -- ::= { snmpv3TargetEntry 5 }
+
+-- Custom Trap Message
+
+customTrapMSG NOTIFICATION-TYPE
+ STATUS current
+ --OBJECTS { customTrapMSG }
+ DESCRIPTION "Display custom trap message."
+ ::= { pe 5 }
+
+rebootDevice OBJECT-TYPE
+ SYNTAX INTEGER { no(1), yes(2) }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION "Reboot PE Device"
+ ::= { pe 6 }
+-- CPM
+--modelName OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Indicate CPM device model name."
+-- ::= { CPM 1 }
+
+--cpmName OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "The name of CPM device.
+-- string length: 1~39
+-- NOTE: Input string as /empty to set this object to NULL.
+-- "
+-- ::= { CPM 2 }
+
+--cpmswitchable OBJECT-TYPE
+-- SYNTAX INTEGER { no(1), yes(2) }
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- " Switchable or not. "
+-- ::= { CPM 3 }
+
+--cpmPDUreading OBJECT-TYPE
+-- SYNTAX INTEGER { no(1), yes(2) }
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- " CPM is per-PDU reading or not."
+-- ::= { CPM 4 }
+
+--cpmSensornumber OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- " CPM's Sensor number."
+-- ::= { CPM 5 }
+
+--cpmOutletnumber OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- " CPM's Outlet number."
+-- ::= { CPM 6 }
+
+--cpmbreaker OBJECT-TYPE
+ --SYNTAX INTEGER { off(1), on(2) }
+ --MAX-ACCESS read-only
+ --STATUS current
+ --DESCRIPTION
+ -- "CPM's breaker status."
+ --::= { CPM 7 }
+
+-- Device
+--cpmdeviceValueTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF cpmDeviceValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Device value table. This table displays device's current.
+-- "
+-- ::= { CPMDevice 1 }
+
+--cpmdeviceValueEntry OBJECT-TYPE
+-- SYNTAX cpmDeviceValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Single deviceValue entry containing device info."
+-- INDEX { cpmdeviceValueIndex }
+-- ::= { cpmdeviceValueTable 1 }
+
+--cpmDeviceValueEntry ::=
+-- SEQUENCE {
+-- cpmdeviceValueIndex
+-- INTEGER,
+-- cpmdeviceCurrent
+-- DisplayString,
+ --cpmdeviceVoltage
+ -- DisplayString,
+ --cpmdevicePower
+ -- DisplayString,
+ --cpmdevicePowerDissipation
+ -- DisplayString,
+ --cpminputMaxVoltage
+ -- INTEGER,
+-- cpminputMaxCurrent
+-- INTEGER
+ --cpmpowerCapacity
+ -- INTEGER
+
+-- }
+
+--cpmdeviceValueIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Index of device Value."
+-- ::= { cpmdeviceValueEntry 1 }
+
+--cpmdeviceCurrent OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device electric current value.
+-- "
+-- ::= { cpmdeviceValueEntry 2 }
+
+--cpmdeviceVoltage OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device voltage value."
+-- ::= { cpmdeviceValueEntry 3 }
+--cpmdevicePower OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device power value."
+-- ::= { cpmdeviceValueEntry 4 }
+
+--cpmdevicePowerDissipation OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device power dissipation value."
+-- ::= { cpmdeviceValueEntry 5 }
+
+--cpminputMaxVoltage OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device input Voltage value. unit:(V)"
+-- ::= { cpmdeviceValueEntry 6 }
+
+--cpminputMaxCurrent OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device input Current value. unit:(A)"
+-- ::= { cpmdeviceValueEntry 7 }
+
+--cpmpowerCapacity OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "Device power Capacity value.unit:(VA)"
+-- ::= { cpmdeviceValueEntry 8 }
+
+--cpmdeviceConfigTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF cpmDeviceConfigEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Device configuration table"
+-- ::= { CPMDevice 2 }
+
+--cpmdeviceConfigEntry OBJECT-TYPE
+-- SYNTAX cpmDeviceConfigEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Single deviceConfig entry containing device info."
+-- INDEX { cpmdeviceConfigIndex }
+-- ::= { cpmdeviceConfigTable 1 }
+
+--cpmDeviceConfigEntry ::=
+-- SEQUENCE {
+-- cpmdeviceConfigIndex
+-- INTEGER,
+ --cpmdeviceMinCurMT
+ -- INTEGER,
+-- cpmdeviceMaxCurMT
+-- INTEGER
+ --cpmdeviceMinVolMT
+ -- INTEGER,
+ --cpmdeviceMaxVolMT
+ -- INTEGER,
+-- }
+
+--cpmdeviceConfigIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Index of deviceConfig"
+-- ::= { cpmdeviceConfigEntry 1 }
+
+--cpmdeviceMinCurMT OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set device minimum electric current measurement threshold.
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+-- range:0.0~32.0 represents:0~320
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmdeviceConfigEntry 2 }
+
+--cpmdeviceMaxCurMT OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set device maximum electric current measurement threshold.
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+-- Example: range 0.0~32.0 represents: 0~320
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmdeviceConfigEntry 3 }
+
+--cpmdeviceMinVolMT OBJECT-TYPE
+-- SYNTAX INTEGER (900..2600 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set device minimum voltage measurement threshold.
+-- range:90.0~260.0 represents:900~2600
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmdeviceConfigEntry 4 }
+
+--cpmdeviceMaxVolMT OBJECT-TYPE
+-- SYNTAX INTEGER (900..2600 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set device maximum voltage measurement threshold.
+-- range:90.0~260.0 represents:900~2600
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmdeviceConfigEntry 5 }
+
+
+
+-- Sensor
+--cpmSensorValueTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF cpmSensorValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's sensor value table. This table displays sensor's temperature, humidity and
+-- pressure.
+-- "
+-- ::= { Sensor 1 }
+
+--cpmSensorValueEntry OBJECT-TYPE
+-- SYNTAX cpmSensorValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's sensor value entry containing Sensor info."
+-- INDEX { cpmSensorValueIndex }
+-- ::= { cpmSensorValueTable 1 }
+
+--cpmSensorValueEntry ::=
+-- SEQUENCE {
+-- cpmSensorValueIndex
+-- INTEGER,
+-- cpmSensorTemperature
+-- DisplayString,
+-- cpmSensorHumidity
+-- DisplayString,
+-- cpmSensorPressure
+-- DisplayString,
+-- cpmSensorProperty
+-- INTEGER
+-- }
+
+--cpmSensorValueIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1..4)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Index of CPM's Sensor number."
+-- ::= { cpmSensorValueEntry 1 }
+
+--cpmSensorTemperature OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's Sensor Temperature value."
+-- ::= { cpmSensorValueEntry 2 }
+
+--cpmSensorHumidity OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's Sensor Humidity value."
+-- ::= { cpmSensorValueEntry 3 }
+
+--cpmSensorPressure OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's Sensor Pressure value."
+-- ::= { cpmSensorValueEntry 4 }
+
+--cpmSensorProperty OBJECT-TYPE
+-- SYNTAX INTEGER { intake(1), exhaust(2) }
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's Sensor Property."
+-- ::= { cpmSensorValueEntry 5 }
+
+--cpmSensorThresholdTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF cpmSensorThresholdEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's Sensor value table"
+-- ::= { Sensor 2 }
+
+--cpmSensorThresholdEntry OBJECT-TYPE
+-- SYNTAX cpmSensorThresholdEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's sensor threshold entry containing sensor info."
+-- INDEX { cpmSensorThresholdIndex }
+-- ::= { cpmSensorThresholdTable 1 }
+
+--cpmSensorThresholdEntry ::=
+-- SEQUENCE {
+-- cpmSensorThresholdIndex
+-- INTEGER,
+-- cpmsensorMinTempMT
+-- INTEGER,
+-- cpmsensorMaxTempMT
+-- INTEGER,
+
+-- cpmsensorMinHumMT
+-- INTEGER,
+-- cpmsensorMaxHumMT
+-- INTEGER,
+-- cpmsensorMinPressMT
+-- INTEGER,
+-- cpmsensorMaxPressMT
+-- INTEGER
+ --sensorTempFlu
+ --INTEGER,
+ --sensorHumFlu
+ --INTEGER,
+ --sensorPressFlu
+ --INTEGER
+-- }
+
+--cpmSensorThresholdIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1..4)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Index of CPM's sensor number"
+-- ::= { cpmSensorThresholdEntry 1 }
+
+--cpmsensorMinTempMT OBJECT-TYPE
+-- SYNTAX INTEGER (-200..600 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set sensor minimum temperature measurement threshold.
+-- Example: range 0.0 ~ 60.0 represents 0~600
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold.
+-- "
+-- ::= { cpmSensorThresholdEntry 2 }
+
+--cpmsensorMaxTempMT OBJECT-TYPE
+-- SYNTAX INTEGER (-200..600 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set sensor maximum temperature measurement threshold.
+-- Example: range 0.0 ~ 60.0 represents 0~600
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmSensorThresholdEntry 3 }
+
+--cpmsensorMinHumMT OBJECT-TYPE
+-- SYNTAX INTEGER (150..950 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set sensor minimum humidity measurement threshold.
+-- Example: range 15.0 ~ 95.0 represents 150~950
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmSensorThresholdEntry 4 }
+--cpmsensorMaxHumMT OBJECT-TYPE
+-- SYNTAX INTEGER (150..950 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set sensor maximum humidity measurement threshold.
+-- Example: range 15.0 ~ 95.0 represents 150~950
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmSensorThresholdEntry 5 }
+
+--cpmsensorMinPressMT OBJECT-TYPE
+-- SYNTAX INTEGER (-2500..2500 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set sensor minimum pressure measurement threshold.
+-- Example: range -250.0 ~ 250.0 represents -2500 ~ 2500
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmSensorThresholdEntry 6 }
+
+--cpmsensorMaxPressMT OBJECT-TYPE
+-- SYNTAX INTEGER (-2500..2500 | -3000)
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set sensor maximum pressure measurement threshold.
+-- Example: range -250.0 ~ 250.0 represents -2500 ~ 2500
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmSensorThresholdEntry 7 }
+
+
+-- pdu
+
+--cpmPDUValueTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF cpmPDUValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Display the PDU's current value of CPM"
+-- ::= { EnergySensor 1 }
+
+--cpmPDUValueEntry OBJECT-TYPE
+-- SYNTAX cpmPDUValueEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's monitor pdu Value entry containing outlet info."
+-- INDEX { cpmPDUValueIndex }
+-- ::= { cpmPDUValueTable 1 }
+
+--cpmPDUValueEntry ::=
+-- SEQUENCE {
+-- cpmPDUValueIndex
+-- INTEGER,
+-- cpmPDUCurrent
+-- DisplayString,
+ --cpmPDUVoltage
+ -- DisplayString,
+ --cpmPDUPower
+ -- DisplayString,
+ --cpmPDUPowerDissipation
+ -- DisplayString,
+-- cpmPDUMaxCurrent
+-- INTEGER
+-- }
+
+--cpmPDUValueIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1..4)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Index of PDU number"
+-- ::= { cpmPDUValueEntry 1 }
+
+--cpmPDUCurrent OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's monitor PDU electric current value"
+-- ::= { cpmPDUValueEntry 2 }
+
+--cpmPDUVoltage OBJECT-TYPE
+ --SYNTAX DisplayString
+ --MAX-ACCESS read-only
+ --STATUS current
+ --DESCRIPTION
+ -- "CPM's monitor PDU voltage value"
+ --::= { cpmPDUValueEntry 3 }
+
+--cpmPDUPower OBJECT-TYPE
+ --SYNTAX DisplayString
+ --MAX-ACCESS read-only
+ --STATUS current
+ --DESCRIPTION
+ -- "CPM's monitor PDU power value"
+ --::= { cpmPDUValueEntry 4 }
+
+--cpmPDUPowerDissipation OBJECT-TYPE
+ --SYNTAX DisplayString
+ --MAX-ACCESS read-only
+ --STATUS current
+ --DESCRIPTION
+ -- "CPM's monitor PDU power dissipation value"
+ --::= { cpmPDUValueEntry 5 }
+
+--cpmPDUMaxCurrent OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's monitor PDU Max Current value. unit: (A)"
+-- ::= { cpmPDUValueEntry 6 }
+
+--cpmBankStatus OBJECT-TYPE
+-- SYNTAX INTEGER { noattached(1), attached(2) }
+-- MAX-ACCESS read-only
+-- STATUS current
+-- DESCRIPTION
+-- "The status CPM device Bank status."
+-- ::= { cpmPDUValueEntry 7 }
+
+
+--cpmPDUConfigTable OBJECT-TYPE
+-- SYNTAX SEQUENCE OF cpmPDUConfigEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's monitor PDU configuration table"
+-- ::= { EnergySensor 2 }
+
+--cpmPDUConfigEntry OBJECT-TYPE
+-- SYNTAX cpmPDUConfigEntry
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "CPM's monitor PDU config entry containing PDU info."
+-- INDEX { cpmPDUConfigIndex }
+-- ::= { cpmPDUConfigTable 1 }
+
+--cpmPDUConfigEntry ::=
+-- SEQUENCE {
+-- cpmPDUConfigIndex
+-- INTEGER,
+-- cpmPDUName
+-- DisplayString,
+ --cpmPDUConfirmation
+ -- INTEGER,
+ --cpmPDUOnDelayTime
+ -- INTEGER,
+ --cpmPDUOffDelayTime
+ -- INTEGER,
+ --cpmPDUShutdownMethod
+ -- INTEGER,
+ --cpmPDUMAC
+ -- DisplayString,
+ --cpmPDUMinCurMT
+ -- INTEGER,
+-- cpmPDUMaxCurMT
+-- INTEGER
+
+ --cpmPDUMinVolMT
+ -- INTEGER,
+ --cpmPDUMaxVolMT
+ -- INTEGER,
+
+
+-- }
+
+--cpmPDUConfigIndex OBJECT-TYPE
+-- SYNTAX INTEGER (1..4)
+-- MAX-ACCESS not-accessible
+-- STATUS current
+-- DESCRIPTION
+-- "Index of PDU number"
+-- ::= { cpmPDUConfigEntry 1 }
+
+--cpmPDUName OBJECT-TYPE
+-- SYNTAX DisplayString
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set the name of pdu.
+-- string length: 0~15
+-- NOTE: Input string as /empty to set this object to NULL.
+-- "
+-- ::= { cpmPDUConfigEntry 2 }
+
+--cpmPDUConfirmation OBJECT-TYPE
+ --SYNTAX INTEGER { no(1), yes(2) }
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the confirmation of outlet."
+ --::= { cpmPDUConfigEntry 3 }
+
+--cpmPDUOnDelayTime OBJECT-TYPE
+ --SYNTAX INTEGER (0..999)
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the ON delay time of outlet."
+ --::= { cpmPDUConfigEntry 4 }
+
+--cpmPDUOffDelayTime OBJECT-TYPE
+ --SYNTAX INTEGER (0..999)
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the OFF delay time of outlet."
+ --::= { cpmPDUConfigEntry 5 }
+
+--cpmPDUShutdownMethod OBJECT-TYPE
+ --SYNTAX INTEGER { kill-the-power(1), wake-on-lan(2), after-ac-back(3) }
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the shutdown mehtod of outlet."
+ --::= { cpmPDUConfigEntry 6 }
+
+--cpmPDUMAC OBJECT-TYPE
+ --SYNTAX DisplayString
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the MAC address of ShutdownMethod.
+ -- string length: 12
+ -- "
+ --::= { cpmPDUConfigEntry 7 }
+
+--cpmPDUMinCurMT OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set the PDU minimum electric current measurment threshold.
+-- Range:0.0 ~16.0 rerpresnts 0~160
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+--
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmPDUConfigEntry 3 }
+
+--cpmPDUMaxCurMT OBJECT-TYPE
+-- SYNTAX INTEGER
+-- MAX-ACCESS read-write
+-- STATUS current
+-- DESCRIPTION
+-- "Display or set the PDU maximum electric current measurment threshold.
+-- Example: range 0.0 ~16.0 represents 0~160
+-- When this value is -3000,it indicate this is NULL.
+-- When set this value to -3000, indicate set this object as NULL.
+
+-- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+-- "
+-- ::= { cpmPDUConfigEntry 4 }
+
+--cpmPDUMinVolMT OBJECT-TYPE
+ --SYNTAX INTEGER (900..2600)
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the outlet minimum voltage measurment threshold.
+ -- Range:90.0 ~260.0 represents 900~2600
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { cpmPDUConfigEntry 10 }
+
+--cpmPDUMaxVolMT OBJECT-TYPE
+ --SYNTAX INTEGER (900..2600)
+ --MAX-ACCESS read-write
+ --STATUS current
+ --DESCRIPTION
+ -- "Display or set the outlet maximum voltage measurment threshold.
+ -- Range:90.0 ~260.0 represents 900~2600
+ -- When this value is -3000,it indicate this is NULL.
+ -- When set this value to -3000, indicate set this object as NULL.
+ -- NOTICE:Minimum threshold should be setted smaller than Maxima threshold
+ -- "
+ --::= { cpmPDUConfigEntry 11 }
+
+
+END
diff --git a/roles/aten_pdu/files/aten-mqtt-publish.sh b/roles/aten_pdu/files/aten-mqtt-publish.sh
new file mode 100755
index 0000000..60803fa
--- /dev/null
+++ b/roles/aten_pdu/files/aten-mqtt-publish.sh
@@ -0,0 +1,93 @@
+#!/bin/sh
+
+set -eu
+umask 077
+
+community="public"
+
+if [ "${1:-}" = "-n" ]; then
+ _noop=true
+else
+ _noop=false
+fi
+
+mqtt_send() {
+ topic="$1"
+ value="$2"
+
+ tlsdir="$(openssl version -d | sed -e 's/^OPENSSLDIR: "\(.\+\)"$/\1/')"
+ mosquitto_pub -h mqtt02.home.foo.sh -t "$topic" -m "$value" \
+ --cafile "${tlsdir}/certs/ca.crt" \
+ --key "${tlsdir}/private/$(hostname -f).key" \
+ --cert "${tlsdir}/certs/$(hostname -f).crt"
+}
+
+snmp_get() {
+ host="$1"
+ key="$2"
+ snmpget -v 1 -c "$community" "$host" -Oqv -m ATEN-PE-CFG "$key" | tr -d '"'
+}
+
+# only run script if first vrrp interface is in master state
+for state in /run/keepalived/*.state ; do
+ if [ "$(cat "$state")" != "MASTER" ]; then
+ exit 0
+ fi
+ break
+done
+
+ldapsearch -Q -LLL "(&(objectClass=device)(description=Aten PE*))" cn l | awk '
+ {
+ if ($1 == "cn:") {
+ cn = $2
+ }
+ if ($1 == "l:") {
+ l = substr($0, 3)
+ }
+ if ($0 == "" && cn != "" && l != "") {
+ print cn l
+ cn = ""
+ l = ""
+ }
+ }
+ ' | while read -r name location
+do
+ snmpwalk -v 1 -c "$community" "$name" -Oq \
+ -m ATEN-PE-CFG ATEN-PE-CFG::outletName | while read -r port device
+ do
+ port="$(echo "$port" | cut -d '.' -f 2)"
+ device="$(echo "$device" | tr -d '"')"
+ case "$device" in
+ "N/A"|"00 "|"unused")
+ continue
+ ;;
+ esac
+ if device_name="$(ldapsearch -Q -LLL \
+ "(&(objectClass=device)(cn=${device}.*))" cn | awk "
+ {
+ if (\$1 == \"cn:\") {
+ if (name) {
+ exit 1
+ }
+ name=\$2
+ }
+ } END {
+ if (!name) {
+ exit 1
+ }
+ print name
+ }
+ ")" ; then
+ device="$device_name"
+ fi
+ for key in Current Power Voltage ; do
+ topic="home/${location}/${device}/$(echo "$key" | tr '[:upper:]' '[:lower:]')"
+ value="$(snmp_get "$name" "ATEN-PE-CFG::outlet${key}.${port}")"
+ if $_noop ; then
+ echo "${topic} -> ${value}"
+ else
+ mqtt_send "$topic" "$value"
+ fi
+ done
+ done
+done
diff --git a/roles/aten_pdu/meta/main.yml b/roles/aten_pdu/meta/main.yml
new file mode 100644
index 0000000..d2f9d51
--- /dev/null
+++ b/roles/aten_pdu/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: ldap}
diff --git a/roles/aten_pdu/tasks/main.yml b/roles/aten_pdu/tasks/main.yml
new file mode 100644
index 0000000..8bb9112
--- /dev/null
+++ b/roles/aten_pdu/tasks/main.yml
@@ -0,0 +1,31 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: installed
+ with_items:
+ - mosquitto
+ - net-snmp-utils
+
+# https://www.aten.com/eu/en/products/power-distribution-&-racks/rack-pdu/pe8108/
+- name: Install custom mib
+ ansible.builtin.copy:
+ dest: /usr/share/snmp/mibs/ATEN-PE-CFG.txt
+ src: ATEN-PE-CFG_str_1.3.128.mib
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Install mqtt publish script
+ ansible.builtin.copy:
+ dest: /usr/local/bin/aten-mqtt-publish
+ src: aten-mqtt-publish.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Add mqtt publish cron job
+ ansible.builtin.cron:
+ name: aten-mqtt-publish
+ job: /usr/local/bin/aten-mqtt-publish
+ minute: "*/5"
diff --git a/roles/audiobookshelf/files/audiobookshelf.default b/roles/audiobookshelf/files/audiobookshelf.default
new file mode 100644
index 0000000..4b553f5
--- /dev/null
+++ b/roles/audiobookshelf/files/audiobookshelf.default
@@ -0,0 +1,4 @@
+METADATA_PATH=/srv/audiobookshelf/metadata
+CONFIG_PATH=/srv/audiobookshelf/config
+PORT=13378
+HOST=127.0.0.1
diff --git a/roles/audiobookshelf/files/meta.md b/roles/audiobookshelf/files/meta.md
new file mode 100644
index 0000000..5e22e02
--- /dev/null
+++ b/roles/audiobookshelf/files/meta.md
@@ -0,0 +1,30 @@
+= Preparing files for upload =
+
+== Filenames ==
+
+Filenames should always contain track number (and optionally disc number) with leading zeros first and subtitle after that. Few exmaples:
+
+```
+01. Luku.mp3
+01. Osa.mp3
+CD 1 - 01.mp3
+```
+
+Directory should also contain `cover.jpg` with book cover picture and `desc.txt` containing book description.
+
+== Metadata (id3 tags) ==
+
+First clear old tags then set new ones:
+
+```
+id3v2 -D "01. Osa.mp3"
+id3v2 \
+ --TPE1 "Douglas Adams" \
+ --TALB "$(echo 'Linnunradan käsikirja liftareille' | iconv -f utf-8 -t iso-8859-1)" \
+ --TCOM "$(echo 'Heikki Kinnunen,Pekka Autiovuori,Yrjö Järvinen,Martti Järvinen,Esa Saario,Kauko Helavirta,Aila Svedberg' | iconv -f utf-8 -t iso-8859-1)" \
+ --TLAN "fi" \
+ --TPUB "Yleisradio" \
+ --TYER 1984 \
+ --genre "Science Fiction/Fiction/Humor" \
+ "01. Osa.mp3"
+```
diff --git a/roles/audiobookshelf/handlers/main.yml b/roles/audiobookshelf/handlers/main.yml
new file mode 100644
index 0000000..fd2df00
--- /dev/null
+++ b/roles/audiobookshelf/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart audiobookshelf
+ ansible.builtin.service:
+ name: audiobookshelf
+ state: restarted
diff --git a/roles/audiobookshelf/meta/main.yml b/roles/audiobookshelf/meta/main.yml
new file mode 100644
index 0000000..954fabd
--- /dev/null
+++ b/roles/audiobookshelf/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: nginx}
diff --git a/roles/audiobookshelf/tasks/main.yml b/roles/audiobookshelf/tasks/main.yml
new file mode 100644
index 0000000..1bc2f99
--- /dev/null
+++ b/roles/audiobookshelf/tasks/main.yml
@@ -0,0 +1,90 @@
+---
+- name: Enable repository
+ ansible.builtin.yum_repository:
+ name: audiobookshelf
+ baseurl: https://raw.githubusercontent.com/lkiesow/audiobookshelf-rpm/el$releasever/
+ description: Audiobookshelf el$releasever repository
+ gpgcheck: true
+ gpgkey: https://raw.githubusercontent.com/lkiesow/audiobookshelf-rpm/main/audiobookshelf-rpm.key
+ enabled: true
+
+- name: Install packcages
+ ansible.builtin.package:
+ name: audiobookshelf
+ state: present
+
+- name: Create data directories
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: directory
+ mode: "0770"
+ owner: root
+ group: audiobookshelf
+ with_items:
+ - /export/audiobookshelf
+ - /export/audiobookshelf/audiobooks
+ - /export/audiobookshelf/config
+ - /export/audiobookshelf/metadata
+ - /export/audiobookshelf/podcasts
+ - /export/audiobookshelf/radioplays
+
+- name: Link data directory
+ ansible.builtin.file:
+ dest: /srv/audiobookshelf
+ src: /export/audiobookshelf
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+
+- name: Copy naming instructions
+ ansible.builtin.copy:
+ dest: /srv/audiobookshelf/audiobooks/README.md
+ src: meta.md
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Copy service config
+ ansible.builtin.copy:
+ dest: /etc/default/audiobookshelf
+ src: audiobookshelf.default
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart audiobookshelf
+
+- name: Enable service
+ ansible.builtin.service:
+ name: audiobookshelf
+ state: started
+ enabled: true
+
+- name: Allow nginx to connect audiobookshelf
+ ansible.posix.seboolean:
+ name: httpd_can_network_connect
+ state: true
+ persistent: true
+
+- name: Copy nginx config
+ ansible.builtin.copy:
+ dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/audiobookshelf.conf"
+ content: |
+ location / {
+ proxy_set_header Connection $connection_upgrade;
+ proxy_set_header Host audiobooks.foo.sh;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_http_version 1.1;
+ proxy_pass http://127.0.0.1:13378/;
+ location /audiobookshelf/api/upload {
+ # increase size to allow uploads
+ client_max_body_size 10g;
+ proxy_pass http://127.0.0.1:13378/api/upload;
+ }
+ }
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
diff --git a/roles/authcheck/tasks/main.yml b/roles/authcheck/tasks/main.yml
index 222d5b4..8ca80cf 100644
--- a/roles/authcheck/tasks/main.yml
+++ b/roles/authcheck/tasks/main.yml
@@ -10,11 +10,19 @@
group: authcheck
shell: /sbin/nologin
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - authcheck
+ creates: /var/lib/systemd/linger/authcheck
+
- name: Get container source
ansible.builtin.git:
dest: /usr/local/src/docker-authcheck
repo: https://github.com/foo-sh/docker-authcheck.git
- update: false
+ update: true
version: main
notify: Rebuild authcheck-container
@@ -22,7 +30,7 @@
ansible.builtin.template:
dest: /etc/systemd/system/authcheck-container.service
src: authcheck-container.service.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -39,7 +47,7 @@
location /authcheck {
proxy_pass http://127.0.0.1:8003/;
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
diff --git a/roles/autofs/defaults/main.yml b/roles/autofs/defaults/main.yml
new file mode 100644
index 0000000..404004a
--- /dev/null
+++ b/roles/autofs/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+autofs_home: true
+autofs_roles: true
diff --git a/roles/autofs/tasks/main.yml b/roles/autofs/tasks/main.yml
index d3a3121..19f9565 100644
--- a/roles/autofs/tasks/main.yml
+++ b/roles/autofs/tasks/main.yml
@@ -34,7 +34,7 @@
ansible.builtin.template:
dest: /etc/autofs_ldap_auth.conf
src: autofs_ldap_auth.conf.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart autofs
@@ -43,7 +43,7 @@
ansible.builtin.template:
dest: /etc/auto.master
src: auto.master.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart autofs
@@ -74,7 +74,7 @@
ansible.builtin.copy:
dest: "/etc/profile.d/{{ item }}"
src: "{{ item }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
with_items:
diff --git a/roles/autofs/templates/auto.master.j2 b/roles/autofs/templates/auto.master.j2
index ee9e28f..4087487 100644
--- a/roles/autofs/templates/auto.master.j2
+++ b/roles/autofs/templates/auto.master.j2
@@ -1,2 +1,6 @@
-/home ldap:///ou=People,{{ ldap_basedn }} rw,nosuid,nodev,rsize=1048576,wsize=1048576
-/roles ldap:///ou=Groups,{{ ldap_basedn }} rw,nosuid,nodev,rsize=1048576,wsize=1048576 --ghost
+{% if autofs_home %}
+/home ldap:///ou=People,{{ ldap_basedn }} rw,noatime,nosuid,nodev,rsize=1048576,wsize=1048576,xprtsec=mtls
+{% endif %}
+{% if autofs_roles %}
+/roles ldap:///ou=Groups,{{ ldap_basedn }} rw,noatime,nosuid,nodev,rsize=1048576,wsize=1048576,xprtsec=mtls --ghost
+{% endif %}
diff --git a/roles/backup_base/defaults/main.yml b/roles/backup_base/defaults/main.yml
new file mode 100644
index 0000000..2a14dc3
--- /dev/null
+++ b/roles/backup_base/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+backup_datadir: >-
+ {% if ansible_local['export'] %}/export{% else %}/srv{% endif %}/backup
diff --git a/roles/backup_base/tasks/main.yml b/roles/backup_base/tasks/main.yml
new file mode 100644
index 0000000..cb10097
--- /dev/null
+++ b/roles/backup_base/tasks/main.yml
@@ -0,0 +1,55 @@
+---
+- name: Create backup group
+ ansible.builtin.group:
+ name: backup
+ gid: 306
+
+- name: Create backup user
+ ansible.builtin.user:
+ name: backup
+ comment: Backup Service
+ createhome: false
+ group: backup
+ home: /var/empty
+ shell: /bin/sh
+ uid: 306
+
+- name: Create backup directory
+ ansible.builtin.file:
+ path: "{{ backup_datadir }}"
+ state: directory
+ mode: "0750"
+ owner: root
+ group: backup
+
+- name: Link backup directory
+ ansible.builtin.file:
+ dest: /srv/backup
+ src: "{{ backup_datadir }}"
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+ when: backup_datadir != "/srv/backup"
+
+- name: Create authorized_keys
+ ansible.builtin.copy:
+ dest: /etc/ssh/authorized_keys.backup
+ src: ../files/ssh/backup.pub
+ mode: "0640"
+ owner: root
+ group: backup
+ when: "'sftpbackup' in group_names"
+
+- name: Configure sshd chroot
+ ansible.builtin.blockinfile:
+ path: /etc/ssh/sshd_config
+ block: |
+ Match User backup
+ ChrootDirectory /srv/backup
+ ForceCommand internal-sftp
+ AuthorizedKeysFile /etc/ssh/authorized_keys.backup
+ marker: "# {mark} ANSIBLE MANAGED BLOCK (user backup)"
+ validate: "sshd -t -f %s"
+ when: "'sftpbackup' in group_names"
+ notify: Restart sshd
diff --git a/roles/backup_bitbucket/files/backup-bitbucket.sh b/roles/backup_bitbucket/files/backup-bitbucket.sh
new file mode 100644
index 0000000..a97097e
--- /dev/null
+++ b/roles/backup_bitbucket/files/backup-bitbucket.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+USERS="tmakinen"
+
+set -eu
+umask 027
+
+cd /srv/backup/bitbucket.org
+
+for _user in $USERS ; do
+ curl -sSf "https://api.bitbucket.org/2.0/repositories/${_user}" | \
+ jq -r '.values | .[] | [.name, .scm] | @tsv' | \
+ while read -r _repo _scm
+ do
+ [ "$_scm" = "git" ] || continue
+ _url="https://bitbucket.org/${_user}/${_repo}"
+ _gitdir="${_user}/${_repo}"
+ if [ ! -d "$_gitdir" ]; then
+ mkdir -p "$_gitdir"
+ git --git-dir="$_gitdir" init --quiet --bare
+ fi
+ git --git-dir="$_gitdir" fetch --quiet --force --prune --tags "$_url" "refs/heads/*:refs/heads/*"
+ done
+done
diff --git a/roles/backup_bitbucket/meta/main.yml b/roles/backup_bitbucket/meta/main.yml
new file mode 100644
index 0000000..f178512
--- /dev/null
+++ b/roles/backup_bitbucket/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: backup_base}
diff --git a/roles/backup_bitbucket/tasks/main.yml b/roles/backup_bitbucket/tasks/main.yml
new file mode 100644
index 0000000..d41605a
--- /dev/null
+++ b/roles/backup_bitbucket/tasks/main.yml
@@ -0,0 +1,32 @@
+---
+- name: Install dependencies
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: installed
+ with_items:
+ - git
+ - jq
+
+- name: Create backup directory
+ ansible.builtin.file:
+ path: /srv/backup/bitbucket.org
+ state: directory
+ mode: "0770"
+ owner: root
+ group: backup
+
+- name: Copy backup script
+ ansible.builtin.copy:
+ dest: /usr/local/sbin/backup-bitbucket
+ src: backup-bitbucket.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Add cron job
+ ansible.builtin.cron:
+ name: bitbucket-backup
+ job: /usr/local/sbin/backup-bitbucket
+ hour: "03"
+ minute: "10"
+ user: backup
diff --git a/roles/backup_github/files/backup-github.sh b/roles/backup_github/files/backup-github.sh
new file mode 100755
index 0000000..6d2c598
--- /dev/null
+++ b/roles/backup_github/files/backup-github.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+ORGS="foo-sh"
+
+set -eu
+umask 027
+
+cd /srv/backup/github.com
+
+for _org in $ORGS ; do
+ curl -sSf "https://api.github.com/orgs/foo-sh/repos" | jq -r '.[] | .name' | \
+ while read -r _repo
+ do
+ _url="https://github.com/${_org}/${_repo}.git"
+ _gitdir="${_org}/${_repo}"
+ if [ ! -d "$_gitdir" ]; then
+ mkdir -p "$_gitdir"
+ git --git-dir="$_gitdir" init --quiet --bare
+ fi
+ git --git-dir="$_gitdir" fetch --quiet --force --prune --tags "$_url" "refs/heads/*:refs/heads/*"
+ done
+done
diff --git a/roles/backup_github/meta/main.yml b/roles/backup_github/meta/main.yml
new file mode 100644
index 0000000..f178512
--- /dev/null
+++ b/roles/backup_github/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: backup_base}
diff --git a/roles/backup_github/tasks/main.yml b/roles/backup_github/tasks/main.yml
new file mode 100644
index 0000000..6d6ffdc
--- /dev/null
+++ b/roles/backup_github/tasks/main.yml
@@ -0,0 +1,32 @@
+---
+- name: Install dependencies
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: installed
+ with_items:
+ - git
+ - jq
+
+- name: Create backup directory
+ ansible.builtin.file:
+ path: /srv/backup/github.com
+ state: directory
+ mode: "0770"
+ owner: root
+ group: backup
+
+- name: Copy backup script
+ ansible.builtin.copy:
+ dest: /usr/local/sbin/backup-github
+ src: backup-github.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Add cron job
+ ansible.builtin.cron:
+ name: github-backup
+ job: /usr/local/sbin/backup-github
+ hour: "03"
+ minute: "20"
+ user: backup
diff --git a/roles/backup_server/files/backup-bitbucket.py b/roles/backup_server/files/backup-bitbucket.py
deleted file mode 100644
index 15cb651..0000000
--- a/roles/backup_server/files/backup-bitbucket.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import json
-from subprocess import call
-from urllib.request import urlopen
-
-USERS = ["tmakinen"]
-BACKUPDIR = "/srv/backup/bitbucket.org"
-
-
-def repolist(username):
- f = urlopen(f"https://api.bitbucket.org/2.0/repositories/{username}")
- data = json.load(f)
- f.close()
-
- for repo in data["values"]:
- yield (
- {
- "name": repo["name"],
- "scm": repo["scm"],
- "wiki": repo["has_wiki"],
- "issues": repo["has_issues"],
- }
- )
-
-
-def gitbackup(destination, repo):
- if not os.path.exists(destination):
- os.makedirs(destination)
- call(["git", "clone", "--quiet", repo, destination])
- else:
- os.chdir(destination)
- call(["git", f"--git-dir={destination}/.git", "pull", "--quiet"])
-
-
-if __name__ == "__main__":
- for user in USERS:
- for repo in repolist(user):
- if repo["scm"] == "git":
- gitbackup(
- f"{BACKUPDIR}/{user}/{repo['name']}",
- f"https://bitbucket.org/{user}/{repo['name']}.git",
- )
- if repo["wiki"]:
- gitbackup(
- f"{BACKUPDIR}/{user}/{repo['name']}-wiki",
- f"https://bitbucket.org/{user}/{repo['name']}.git/wiki",
- )
- else:
- raise NotImplementedError("{repo['scm']} repositories not supported")
diff --git a/roles/backup_server/tasks/main.yml b/roles/backup_server/tasks/main.yml
deleted file mode 100644
index 8577419..0000000
--- a/roles/backup_server/tasks/main.yml
+++ /dev/null
@@ -1,64 +0,0 @@
----
-- name: Install packages
- ansible.builtin.package:
- name: "{{ item }}"
- state: installed
- with_items:
- - git
- - rclone
-
-- name: Create backup group
- ansible.builtin.group:
- name: backup
- gid: 1005
-
-- name: Create backup user
- ansible.builtin.user:
- name: backup
- comment: Backup Service
- createhome: false
- group: backup
- home: /var/empty
- shell: /bin/sh
- uid: 1005
-
-- name: Create backup directory
- ansible.builtin.file:
- path: /export/backup
- state: directory
- mode: 0755
- owner: root
- group: "{{ ansible_wheel }}"
-
-- name: Link backup directory
- ansible.builtin.file:
- dest: /srv/backup
- src: /export/backup
- state: link
- owner: root
- group: "{{ ansible_wheel }}"
- follow: false
-
-- name: Create Bitbucket backup directory
- ansible.builtin.file:
- path: /export/backup/bitbucket.org
- state: directory
- mode: 0775
- owner: root
- group: backup
-
-- name: Install Bitbucket backup script
- ansible.builtin.copy:
- dest: /usr/local/sbin/backup-bitbucket
- src: backup-bitbucket.py
- mode: 0755
- owner: root
- group: "{{ ansible_wheel }}"
-
-- name: Add Bitbucket backup cron job
- ansible.builtin.cron:
- name: bitbucket-backup
- job: /usr/local/sbin/backup-bitbucket
- hour: "03"
- minute: "10"
- user: backup
diff --git a/roles/base/files/export.fact.sh b/roles/base/files/export.fact.sh
new file mode 100755
index 0000000..1f3075e
--- /dev/null
+++ b/roles/base/files/export.fact.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -eu
+
+if mount | grep -qE "on /export" ; then
+ echo "true"
+else
+ echo "false"
+fi
diff --git a/roles/base/tasks/OpenBSD.yml b/roles/base/tasks/OpenBSD.yml
index d925bf6..b8ca184 100644
--- a/roles/base/tasks/OpenBSD.yml
+++ b/roles/base/tasks/OpenBSD.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
dest: /etc/myname
content: "{{ inventory_hostname }}\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -11,7 +11,7 @@
ansible.builtin.copy:
dest: /etc/installurl
content: "https://mirrors.foo.sh/openbsd/\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
when: ansible_datacenter == "home"
@@ -30,7 +30,7 @@
ansible.builtin.copy:
dest: "{{ item }}"
content: "VERBOSESTATUS=0\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
with_items:
@@ -53,7 +53,7 @@
ansible.builtin.file:
name: /srv
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -64,5 +64,6 @@
- opensmtpd
- pf
- syslogd
+ - unwind
loop_control:
loop_var: role
diff --git a/roles/base/tasks/RedHat.yml b/roles/base/tasks/RedHat.yml
index 8e6ca6e..0e477a1 100644
--- a/roles/base/tasks/RedHat.yml
+++ b/roles/base/tasks/RedHat.yml
@@ -3,6 +3,31 @@
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
+- name: Check if dnf python bindings are installed
+ ansible.builtin.command:
+ argv:
+ - rpm
+ - "-q"
+ - python3-dnf
+ register: result
+ failed_when: false
+ changed_when: false
+
+- name: Install dnf python bindings
+ ansible.builtin.command:
+ argv:
+ - dnf
+ - install
+ - "-y"
+ - python3-dnf
+ when: result.rc != 0
+
+- name: Install OS specific roles for physical hardware
+ ansible.builtin.include_role:
+ name: cpupower
+ when:
+ - ansible_virtualization_role == "host"
+
- name: Install OS specific roles
ansible.builtin.include_role:
name: "{{ role }}"
@@ -12,6 +37,11 @@
loop_control:
loop_var: role
+- name: Install systemd-resolved
+ ansible.builtin.include_role:
+ name: systemd_resolved
+ when: ansible_distribution == "Fedora"
+
- name: Install firewall
ansible.builtin.include_role:
name: iptables
@@ -81,17 +111,24 @@
- vim-enhanced # working vi :)
- xterm # resize
+- name: Install roles for physical hardware
+ ansible.builtin.include_role:
+ name: fwupd
+ when:
+ - ansible_virtualization_role == "host"
+
- name: Install packages for physical hardware
ansible.builtin.package:
name: "{{ item }}"
state: installed
with_items:
+ - hdparm
- pciutils
- powertop
when:
- ansible_virtualization_role == "host"
-- name: Install el7/el8 packages
+- name: Install packages (el8 and older)
ansible.builtin.package:
name: "{{ item }}"
state: installed
@@ -99,7 +136,7 @@
- mailx
when: ansible_distribution_major_version|int <= 8
-- name: Install el9 packages
+- name: Install packages (el9 and newer)
ansible.builtin.package:
name: "{{ item }}"
state: installed
@@ -112,18 +149,39 @@
dest: /etc/GREP_COLORS
state: absent
+- name: Check date format
+ ansible.builtin.shell:
+ cmd: |
+ set -o pipefail
+ localectl status | grep -E '^\s+LC_TIME=C.UTF-8$'
+ executable: /bin/bash
+ register: locale_check
+ changed_when: false
+ failed_when: false
+ check_mode: false
+
+- name: Set date format to use 24 hour clock
+ ansible.builtin.command:
+ argv:
+ - localectl
+ - set-locale
+ - LC_TIME=C.UTF-8
+ register: result
+ changed_when: result.rc == 0
+ when: locale_check.rc != 0
+
- name: Store date and time for bash history
ansible.builtin.copy:
dest: /etc/profile.d/history.sh
content: 'export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "'
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
-- name: Cron job for downloading yum updates
+- name: Cron job for downloading updates
ansible.builtin.cron:
- name: yum-downloadonly
+ name: dnf-downloadonly
user: root
hour: "3"
minute: "{{ 59 | random(seed=inventory_hostname) }}"
- job: "yum -d 0 -e 0 -y --downloadonly update > /dev/null"
+ job: "dnf-3 -q -y update --downloadonly"
diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml
index 5281333..cf661ed 100644
--- a/roles/base/tasks/main.yml
+++ b/roles/base/tasks/main.yml
@@ -1,8 +1,28 @@
---
+- name: Group by domainname
+ ansible.builtin.group_by:
+ key: "{{ inventory_hostname.split('.')[1] }}"
+ changed_when: false
+ when: inventory_hostname | split('.') | length == 4
+
+- name: Get ansible server name
+ ansible.builtin.command:
+ argv:
+ - hostname
+ - -f
+ changed_when: false
+ delegate_to: localhost
+ register: result
+
+- name: Store ansible server name
+ ansible.builtin.set_fact:
+ ansible_server: "{{ result.stdout }}"
+ cacheable: false
+
- name: Setup ansible custom facts
ansible.builtin.file:
dest: "{{ item }}"
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
state: directory
@@ -13,14 +33,8 @@
- name: Add ansible_export fact
ansible.builtin.copy:
dest: /etc/ansible/facts.d/export.fact
- content: |
- #!/bin/sh
- if [ -d /export ]; then
- echo "true"
- else
- echo "false"
- fi
- mode: 0755
+ src: export.fact.sh
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -36,7 +50,7 @@
ansible.builtin.copy:
content: "\n"
dest: "/etc/at.allow"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
@@ -48,6 +62,8 @@
- pki
- psacct
- sshd
+ - sshd_cert
+ - node_exporter
loop_control:
loop_var: role
diff --git a/roles/blackbox_exporter/files/blackbox.yml b/roles/blackbox_exporter/files/blackbox.yml
new file mode 100644
index 0000000..9152489
--- /dev/null
+++ b/roles/blackbox_exporter/files/blackbox.yml
@@ -0,0 +1,17 @@
+---
+modules:
+ http:
+ prober: http
+ http:
+ valid_status_codes:
+ - 200
+ - 401
+ - 403
+ ssh:
+ prober: tcp
+ tcp:
+ query_response:
+ - expect: "^SSH-2.0-"
+ - send: "SSH-2.0-blackbox-ssh-check"
+ tcp:
+ prober: tcp
diff --git a/roles/blackbox_exporter/handlers/main.yml b/roles/blackbox_exporter/handlers/main.yml
new file mode 100644
index 0000000..34e0f2d
--- /dev/null
+++ b/roles/blackbox_exporter/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart blackbox_exporter
+ ansible.builtin.service:
+ name: blackbox_exporter
+ state: restarted
diff --git a/roles/blackbox_exporter/tasks/main.yml b/roles/blackbox_exporter/tasks/main.yml
new file mode 100644
index 0000000..ade2edd
--- /dev/null
+++ b/roles/blackbox_exporter/tasks/main.yml
@@ -0,0 +1,40 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: blackbox_exporter
+ state: installed
+
+- name: Add user to hostkey group
+ ansible.builtin.user:
+ name: _blackboxexporter
+ groups: hostkey
+ append: true
+ create_home: false
+ notify: Restart blackbox_exporter
+
+- name: Create main config
+ ansible.builtin.copy:
+ dest: /etc/blackbox_exporter/blackbox.yml
+ src: blackbox.yml
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart blackbox_exporter
+
+- name: Create web-config
+ ansible.builtin.template:
+ dest: /etc/blackbox_exporter/web-config.yml
+ src: web-config.yml.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart blackbox_exporter
+
+- name: Enable service
+ ansible.builtin.service:
+ name: blackbox_exporter
+ state: started
+ arguments: >
+ --config.file=/etc/blackbox_exporter/blackbox.yml
+ --web.config.file=/etc/blackbox_exporter/web-config.yml
+ enabled: true
diff --git a/roles/blackbox_exporter/templates/web-config.yml.j2 b/roles/blackbox_exporter/templates/web-config.yml.j2
new file mode 100644
index 0000000..03e5466
--- /dev/null
+++ b/roles/blackbox_exporter/templates/web-config.yml.j2
@@ -0,0 +1,11 @@
+---
+tls_server_config:
+ key_file: {{ tls_private }}/{{ inventory_hostname }}.key
+ cert_file: {{ tls_certs }}/{{ inventory_hostname }}.crt
+ client_ca_file: {{ tls_certs }}/ca.crt
+ client_auth_type: RequireAndVerifyClientCert
+ client_allowed_sans:
+{% for host in groups['prometheus'] %}
+ - {{ host }}
+{% endfor %}
+ min_version: TLS13
diff --git a/roles/certbot/meta/main.yml b/roles/certbot/meta/main.yml
index b95ceec..954fabd 100644
--- a/roles/certbot/meta/main.yml
+++ b/roles/certbot/meta/main.yml
@@ -1,3 +1,3 @@
---
dependencies:
- - {role: nginx/server}
+ - {role: nginx}
diff --git a/roles/certbot/tasks/main.yml b/roles/certbot/tasks/main.yml
index 1d22823..189b36b 100644
--- a/roles/certbot/tasks/main.yml
+++ b/roles/certbot/tasks/main.yml
@@ -7,7 +7,7 @@
- name: Create certbot group
ansible.builtin.group:
name: certbot
- gid: 1002
+ gid: 307
- name: Create certbot user
ansible.builtin.user:
@@ -17,20 +17,20 @@
group: certbot
home: /var/empty
shell: /sbin/nologin
- uid: 1002
+ uid: 307
- name: Add certbot nginx site
ansible.builtin.include_role:
- name: nginx/site
+ name: nginx_site
vars:
- site: certbot.home.foo.sh
+ nginx_site_name: certbot.home.foo.sh
- name: Create certbot .well-known directory
ansible.builtin.file:
path: /srv/web/certbot.home.foo.sh/.well-known
owner: root
group: "{{ ansible_wheel }}"
- mode: 0755
+ mode: "0755"
state: directory
- name: Create certbot directories
@@ -38,7 +38,7 @@
path: "{{ item }}"
owner: root
group: certbot
- mode: 0775
+ mode: "0775"
state: directory
with_items:
- /srv/web/certbot.home.foo.sh/.well-known/acme-challenge
@@ -57,7 +57,7 @@
ansible.builtin.copy:
dest: /etc/letsencrypt/cli.ini
src: cli.ini
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/clamav/tasks/main.yml b/roles/clamav/tasks/main.yml
index 469e46a..bbd796a 100644
--- a/roles/clamav/tasks/main.yml
+++ b/roles/clamav/tasks/main.yml
@@ -12,7 +12,7 @@
ansible.builtin.copy:
dest: /etc/tmpfiles.d/clamd.scan.conf
content: "d /run/clamd.scan 711 clamscan clamscan"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Refresh clamd socket directory
diff --git a/roles/collab/tasks/main.yml b/roles/collab/tasks/main.yml
index 95c1446..b3df48d 100644
--- a/roles/collab/tasks/main.yml
+++ b/roles/collab/tasks/main.yml
@@ -2,7 +2,7 @@
- name: Add graphviz repository
ansible.builtin.yum_repository:
name: graphviz
- baseurl: >
+ baseurl: >-
{{
"https://www2.graphviz.org" +
"/Packages/stable/centos/$releasever/os/$basearch/"
@@ -27,7 +27,7 @@
ansible.builtin.get_url:
url: "https://static.moinmo.in/files/moin-{{ moin_version }}.tar.gz"
dest: "{{ srcdir }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
checksum: sha1:3eb13b4730bd97259a41c4cd500f8433778ff8cf
@@ -57,7 +57,7 @@
ansible.builtin.copy:
src: foosh.py
dest: "{{ srcdir }}/collabbackend/collabbackend/plugin/theme/foosh.py"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -99,13 +99,13 @@
- name: Create group collab
ansible.builtin.group:
name: collab
- gid: 1003
+ gid: 310
- name: Create user collab
ansible.builtin.user:
name: collab
comment: Service Collab
- uid: 1003
+ uid: 310
group: collab
home: /var/lib/collab
shell: /sbin/nologin
@@ -114,14 +114,14 @@
ansible.builtin.copy:
content: "umask 077\n"
dest: /var/lib/collab/.profile
- mode: 0440
+ mode: "0440"
owner: collab
group: collab
- name: Create config directories
ansible.builtin.file:
path: "{{ item }}"
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
state: directory
@@ -133,7 +133,7 @@
ansible.builtin.copy:
src: collab.ini
dest: /etc/local/collab/collab.ini
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -145,7 +145,7 @@
- name: Create data directory
ansible.builtin.file:
path: /export/wikis
- mode: 0755
+ mode: "0755"
owner: root
group: root
seuser: _default
@@ -162,7 +162,7 @@
ansible.builtin.file:
path: /srv/wikis/collab
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: collab
@@ -170,7 +170,7 @@
ansible.builtin.file:
state: directory
path: "{{ item }}"
- mode: 02770
+ mode: "02770"
owner: collab
group: collab
with_items:
@@ -196,7 +196,7 @@
ansible.builtin.copy:
src: collab-htaccess
dest: collab-htaccess
- mode: 0660
+ mode: "0660"
owner: collab
group: collab
@@ -204,7 +204,7 @@
ansible.builtin.copy:
src: "{{ srcdir }}/collabbackend/config/{{ item }}"
dest: /srv/wikis/collab/config/{{ item }}
- mode: 0660
+ mode: "0660"
owner: collab
group: collab
seuser: _default
@@ -220,7 +220,7 @@
ansible.builtin.copy:
src: "{{ srcdir }}/collabbackend/packages/CollabBase.zip"
dest: /var/lib/collab/CollabBase.zip
- mode: 0660
+ mode: "0660"
owner: collab
group: collab
remote_src: true
@@ -265,21 +265,7 @@
ansible.builtin.template:
src: collab.conf.j2
dest: /etc/httpd/conf.local.d/collab.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
-
-- name: Import sftpuser role
- ansible.builtin.import_role:
- name: sftpuser
- vars:
- chroot: /srv/wikis/collab
- user: backup
- publickeys: "{{ backup_publickeys }}"
-
-- name: Add backup user to collab group
- ansible.builtin.user:
- name: backup
- groups: collab
- append: true
diff --git a/roles/cpupower/files/cpupower.sysconfig b/roles/cpupower/files/cpupower.sysconfig
new file mode 100644
index 0000000..a75fd87
--- /dev/null
+++ b/roles/cpupower/files/cpupower.sysconfig
@@ -0,0 +1,3 @@
+# See 'cpupower help' and cpupower(1) for more info
+CPUPOWER_START_OPTS="frequency-set -g ondemand"
+CPUPOWER_STOP_OPTS="frequency-set -g performance"
diff --git a/roles/gitea_runner/handlers/main.yml b/roles/cpupower/handlers/main.yml
similarity index 52%
rename from roles/gitea_runner/handlers/main.yml
rename to roles/cpupower/handlers/main.yml
index 3f4dbfd..c37fd46 100644
--- a/roles/gitea_runner/handlers/main.yml
+++ b/roles/cpupower/handlers/main.yml
@@ -1,5 +1,5 @@
---
-- name: Restart act_runner
+- name: Restart cpupower
ansible.builtin.service:
- name: act_runner
+ name: cpupower
state: restarted
diff --git a/roles/cpupower/tasks/main.yml b/roles/cpupower/tasks/main.yml
new file mode 100644
index 0000000..4cd1f83
--- /dev/null
+++ b/roles/cpupower/tasks/main.yml
@@ -0,0 +1,15 @@
+---
+- name: Copy config
+ ansible.builtin.copy:
+ dest: /etc/sysconfig/cpupower
+ src: cpupower.sysconfig
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart cpupower
+
+- name: Enable service
+ ansible.builtin.service:
+ name: cpupower
+ state: started
+ enabled: true
diff --git a/roles/cups_server/files/cups-ppd/Samsung_ML-3051ND.ppd b/roles/cups_server/files/cups-ppd/Samsung_ML-3051ND.ppd
new file mode 100644
index 0000000..2e13ae2
--- /dev/null
+++ b/roles/cups_server/files/cups-ppd/Samsung_ML-3051ND.ppd
@@ -0,0 +1,219 @@
+*PPD-Adobe: "4.3"
+*%
+*% For information on using this, and to obtain the required backend
+*% script, consult http://www.openprinting.org/
+*%
+*% This file is published under the GNU General Public License
+*%
+*% PPD-O-MATIC (4.0.0 or newer) generated this PPD file. It is for use with
+*% all programs and environments which use PPD files for dealing with
+*% printer capability information. The printer must be configured with the
+*% "foomatic-rip" backend filter script of Foomatic 4.0.0 or newer. This
+*% file and "foomatic-rip" work together to support PPD-controlled printer
+*% driver option access with all supported printer drivers and printing
+*% spoolers.
+*%
+*% To save this file on your disk, wait until the download has completed
+*% (the animation of the browser logo must stop) and then use the
+*% "Save as..." command in the "File" menu of your browser or in the
+*% pop-up manu when you click on this document with the right mouse button.
+*% DO NOT cut and paste this file into an editor with your mouse. This can
+*% introduce additional line breaks which lead to unexpected results.
+*%
+*% You may save this file as 'Samsung-ML-3051ND-Postscript.ppd'
+*%
+*%
+*FormatVersion: "4.3"
+*FileVersion: "1.1"
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*PCFileName: "POSTSCRI.PPD"
+*Manufacturer: "Samsung"
+*Product: "(ML-3051ND)"
+*cupsVersion: 1.0
+*cupsManualCopies: True
+*cupsModelNumber: 2
+*cupsFilter: "application/vnd.cups-postscript 100 foomatic-rip"
+*cupsFilter: "application/vnd.cups-pdf 0 foomatic-rip"
+*%pprRIP: foomatic-rip other
+*ModelName: "Samsung ML-3051ND"
+*ShortNickName: "Samsung ML-3051ND Postscript"
+*NickName: "Samsung ML-3051ND Foomatic/Postscript (recommended)"
+*PSVersion: "(3010.000) 550"
+*PSVersion: "(3010.000) 651"
+*PSVersion: "(3010.000) 652"
+*PSVersion: "(3010.000) 653"
+*PSVersion: "(3010.000) 704"
+*PSVersion: "(3010.000) 705"
+*PSVersion: "(3010.000) 800"
+*PSVersion: "(3010.000) 815"
+*PSVersion: "(3010.000) 850"
+*PSVersion: "(3010.000) 860"
+*PSVersion: "(3010.000) 861"
+*PSVersion: "(3010.000) 862"
+*PSVersion: "(3010.000) 863"
+*PSVersion: "(3010.000) 864"
+*PSVersion: "(3010.000) 870"
+*LanguageLevel: "3"
+*ColorDevice: False
+*DefaultColorSpace: Gray
+*FileSystem: False
+*Throughput: "1"
+*LandscapeOrientation: Plus90
+*TTRasterizer: Type42
+*1284DeviceID: "MFG:Samsung;MDL:ML-3051ND;DRV:DPostscript,R1,M0,TP;"
+
+*driverName Postscript: ""
+*driverType P/PostScript: ""
+*driverUrl: "http://partners.adobe.com/public/developer/ps/index_specs.html"
+*driverObsolete: False
+*driverManufacturerSupplied: False
+
+
+
+
+*HWMargins: 18 36 18 36
+*VariablePaperSize: True
+*MaxMediaWidth: 100000
+*MaxMediaHeight: 100000
+*NonUIOrderDependency: 100 AnySetup *CustomPageSize
+*CustomPageSize True: "pop pop pop
+<>setpagedevice"
+*End
+*ParamCustomPageSize Width: 1 points 36 100000
+*ParamCustomPageSize Height: 2 points 36 100000
+*ParamCustomPageSize Orientation: 3 int 0 0
+*ParamCustomPageSize WidthOffset: 4 points 0 0
+*ParamCustomPageSize HeightOffset: 5 points 0 0
+
+*FoomaticIDs: Samsung-ML-3051ND Postscript
+*FoomaticRIPCommandLine: "cat%A%B%Z"
+*FoomaticRIPNoPageAccounting: True
+
+*OpenGroup: General/General
+
+*OpenUI *PageSize/Page Size: PickOne
+*OrderDependency: 100 AnySetup *PageSize
+*DefaultPageSize: Letter
+*PageSize Letter/US Letter: "<>setpagedevice"
+*PageSize A4/A4: "<>setpagedevice"
+*PageSize 11x17/11x17: "<>setpagedevice"
+*PageSize A3/A3: "<>setpagedevice"
+*PageSize A5/A5: "<>setpagedevice"
+*PageSize B5/B5 (JIS): "<>setpagedevice"
+*PageSize Env10/Envelope #10: "<>setpagedevice"
+*PageSize EnvC5/Envelope C5: "<>setpagedevice"
+*PageSize EnvDL/Envelope DL: "<>setpagedevice"
+*PageSize EnvISOB5/Envelope B5: "<>setpagedevice"
+*PageSize EnvMonarch/Envelope Monarch: "<>setpagedevice"
+*PageSize Executive/Executive: "<>setpagedevice"
+*PageSize Legal/US Legal: "<>setpagedevice"
+*CloseUI: *PageSize
+
+*OpenUI *PageRegion: PickOne
+*OrderDependency: 100 AnySetup *PageRegion
+*DefaultPageRegion: Letter
+*PageRegion Letter/US Letter: "<>setpagedevice"
+*PageRegion A4/A4: "<>setpagedevice"
+*PageRegion 11x17/11x17: "<>setpagedevice"
+*PageRegion A3/A3: "<>setpagedevice"
+*PageRegion A5/A5: "<>setpagedevice"
+*PageRegion B5/B5 (JIS): "<>setpagedevice"
+*PageRegion Env10/Envelope #10: "<>setpagedevice"
+*PageRegion EnvC5/Envelope C5: "<>setpagedevice"
+*PageRegion EnvDL/Envelope DL: "<>setpagedevice"
+*PageRegion EnvISOB5/Envelope B5: "<>setpagedevice"
+*PageRegion EnvMonarch/Envelope Monarch: "<>setpagedevice"
+*PageRegion Executive/Executive: "<>setpagedevice"
+*PageRegion Legal/US Legal: "<>setpagedevice"
+*CloseUI: *PageRegion
+
+*DefaultImageableArea: Letter
+*ImageableArea Letter/US Letter: "18 36 594 756"
+*ImageableArea A4/A4: "18 36 577 806"
+*ImageableArea 11x17/11x17: "18 36 774 1188"
+*ImageableArea A3/A3: "18 36 824 1155"
+*ImageableArea A5/A5: "18 36 403 559"
+*ImageableArea B5/B5 (JIS): "18 36 498 693"
+*ImageableArea Env10/Envelope #10: "18 36 279 648"
+*ImageableArea EnvC5/Envelope C5: "18 36 441 613"
+*ImageableArea EnvDL/Envelope DL: "18 36 294 588"
+*ImageableArea EnvISOB5/Envelope B5: "18 36 481 673"
+*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504"
+*ImageableArea Executive/Executive: "18 36 504 720"
+*ImageableArea Legal/US Legal: "18 36 594 972"
+
+*DefaultPaperDimension: Letter
+*PaperDimension Letter/US Letter: "612 792"
+*PaperDimension A4/A4: "595 842"
+*PaperDimension 11x17/11x17: "792 1224"
+*PaperDimension A3/A3: "842 1191"
+*PaperDimension A5/A5: "421 595"
+*PaperDimension B5/B5 (JIS): "516 729"
+*PaperDimension Env10/Envelope #10: "297 684"
+*PaperDimension EnvC5/Envelope C5: "459 649"
+*PaperDimension EnvDL/Envelope DL: "312 624"
+*PaperDimension EnvISOB5/Envelope B5: "499 709"
+*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
+*PaperDimension Executive/Executive: "522 756"
+*PaperDimension Legal/US Legal: "612 1008"
+
+*OpenUI *Duplex/Double-Sided Printing: PickOne
+*OrderDependency: 130 AnySetup *Duplex
+*DefaultDuplex: None
+*Duplex DuplexNoTumble/Long Edge (Standard): "<>setpagedevice"
+*Duplex DuplexTumble/Short Edge (Flip): "<>setpagedevice"
+*Duplex None/Off: "<>setpagedevice"
+*CloseUI: *Duplex
+
+*OpenUI *Resolution/Resolution: PickOne
+*OrderDependency: 90 AnySetup *Resolution
+*DefaultResolution: 600x600dpi
+*Resolution 150x150dpi/150x150 DPI: "<>setpagedevice"
+*Resolution 300x300dpi/300x300 DPI: "<>setpagedevice"
+*Resolution 600x600dpi/600x600 DPI: "<>setpagedevice"
+*Resolution 1200x1200dpi/1200x1200 DPI: "<>setpagedevice"
+*CloseUI: *Resolution
+
+*CloseGroup: General
+
+
+*% Generic boilerplate PPD stuff as standard PostScript fonts and so on
+
+*DefaultFont: Courier
+*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
+*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
+*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
+*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
+*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
+*Font Bookman-Light: Standard "(001.004S)" Standard ROM
+*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
+*Font Courier: Standard "(002.004S)" Standard ROM
+*Font Courier-Bold: Standard "(002.004S)" Standard ROM
+*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
+*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
+*Font Helvetica: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
+*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
+*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
+*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
+*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
+*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
+*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
+*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
+*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
+*Font Symbol: Special "(001.007S)" Special ROM
+*Font Times-Bold: Standard "(001.007S)" Standard ROM
+*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
+*Font Times-Italic: Standard "(001.007S)" Standard ROM
+*Font Times-Roman: Standard "(001.007S)" Standard ROM
+*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
+*Font ZapfDingbats: Special "(001.004S)" Standard ROM
+
diff --git a/roles/cups_server/tasks/main.yml b/roles/cups_server/tasks/main.yml
index 418a672..849543c 100644
--- a/roles/cups_server/tasks/main.yml
+++ b/roles/cups_server/tasks/main.yml
@@ -8,15 +8,17 @@
ansible.builtin.file:
path: /etc/systemd/system/cups.service.d
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
- name: Configure cups keytab location
ansible.builtin.copy:
dest: /etc/systemd/system/cups.service.d/keytab.conf
- content: "[Service]\nEnvironment=KRB5_KTNAME=FILE:/etc/cups/cups.keytab\n"
- mode: 0644
+ content: |
+ [Service]
+ Environment=KRB5_KTNAME=FILE:/etc/cups/cups.keytab
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -34,11 +36,18 @@
line: "#Listen 631"
notify: Restart cups
+- name: Share printers
+ ansible.builtin.lineinfile:
+ path: /etc/cups/cupsd.conf
+ line: "Port 631"
+ insertbefore: "^Listen .*.sock"
+ notify: Restart cups
+
- name: Set ssl listen port
ansible.builtin.lineinfile:
path: /etc/cups/cupsd.conf
line: "SSLListen 631"
- insertafter: "Listen /var/run/cups/cups.sock"
+ insertafter: "^Listen .*.sock"
notify: Restart cups
- name: Require tls 1.3
@@ -84,20 +93,28 @@
force: true
notify: Restart cups
-- name: Disable printer advertising
+- name: Enable printer sharing
ansible.builtin.lineinfile:
path: /etc/cups/cupsd.conf
regexp: "^Browsing .*"
- line: "Browsing No"
+ line: "Browsing Yes"
notify: Restart cups
- name: Disable unauthenticated access from cups
ansible.builtin.blockinfile:
path: /etc/cups/cupsd.conf
- insertafter: "^"
- block: |
- AuthType Default
- Require user @foosh
+ marker: "{mark}"
+ marker_begin: ""
+ marker_end: ""
+ block: |2
+ AuthType Default
+ Require group foosh
+ Order deny,allow
+
+
+ AuthType Default
+ Require group sysadm
+ Order deny,allow
notify: Restart cups
- name: Configure cups admin group
@@ -111,7 +128,7 @@
ansible.builtin.copy:
dest: "/usr/share/cups/www/{{ item }}"
src: "{{ item }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
with_items:
@@ -122,7 +139,7 @@
ansible.builtin.copy:
dest: /usr/share/cups/templates/header.tmpl
src: header.tmpl
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -137,3 +154,91 @@
name: cups
enabled: true
state: started
+
+- name: Copy ppd files
+ ansible.builtin.copy:
+ dest: /usr/local/share/cups-ppd/
+ src: cups-ppd/
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Get printers from LDAP
+ community.general.ldap_search:
+ attrs:
+ - cn
+ - description
+ - l
+ client_cert: >-
+ {{ hostvars[ansible_server]['tls_certs'] + '/' + ansible_server }}.crt
+ client_key: >-
+ {{ hostvars[ansible_server]['tls_private'] + '/' + ansible_server }}.key
+ dn: "{{ ldap_basedn }}"
+ filter: "(&(objectClass=device)(cn=*.print.foo.sh))"
+ scope: subordinate
+ server_uri: "ldaps://{{ ldap_server[0] }}"
+ delegate_to: localhost
+ register: printers
+
+- name: Get printers list
+ ansible.builtin.command:
+ argv:
+ - lpstat
+ - -e
+ changed_when: false
+ register: result
+
+- name: Add printers
+ ansible.builtin.command:
+ argv:
+ - lpadmin
+ - -D
+ - "{{ item.description }}"
+ - -i
+ - >-
+ {{
+ '/usr/local/share/cups-ppd/' +
+ item.description | regex_replace(' ', '_') +
+ '.ppd'
+ }}
+ - -L
+ - "{{ item.l }}"
+ - -o
+ - media=a4
+ - -o
+ - cupsSNMPSupplies=true
+ - -o
+ - printer-error-policy=abort-job
+ - -o
+ - printer-is-shared=true
+ - -v
+ - "http://{{ item.cn }}:631"
+ - -p
+ - "{{ item.cn | split('.') | first }}"
+ - -E
+ with_items: >-
+ {{
+ printers.results | rejectattr(
+ 'cn',
+ 'in',
+ result.stdout_lines | map('regex_replace', '$', '.print.foo.sh'
+ ) | list) | list
+ }}
+
+- name: Remove printers
+ ansible.builtin.command:
+ argv:
+ - lpadmin
+ - -x
+ - "{{ item }}"
+ with_items: >-
+ {{
+ result.stdout_lines | reject(
+ 'in',
+ printers.results | map(attribute='cn') | map(
+ 'regex_replace',
+ '.print.foo.sh$',
+ ''
+ ) | list
+ ) | list
+ }}
diff --git a/roles/dhcpd/tasks/main.yml b/roles/dhcpd/tasks/main.yml
index 8052208..134b4ed 100644
--- a/roles/dhcpd/tasks/main.yml
+++ b/roles/dhcpd/tasks/main.yml
@@ -7,16 +7,44 @@
name: "{{ dhcpd_package }}"
state: installed
+- name: Get host data from LDAP
+ community.general.ldap_search:
+ attrs:
+ - cn
+ - ipHostNumber
+ - macAddress
+ client_cert: >-
+ {{ hostvars[ansible_server]['tls_certs'] + '/' + ansible_server }}.crt
+ client_key: >-
+ {{ hostvars[ansible_server]['tls_private'] + '/' + ansible_server }}.key
+ dn: "{{ dhcpd_ldap_basedn | default(ldap_basedn) }}"
+ filter: "{{ dhcpd_ldap_filter }}"
+ scope: subordinate
+ server_uri: "ldaps://{{ ldap_server[0] }}"
+ delegate_to: localhost
+ register: ldap_hosts
+ when: dhcpd_ldap_filter is defined
+
- name: Create config
ansible.builtin.template:
dest: "{{ dhcpd_config }}"
src: "{{ dhcpd_template | default('dhcpd.conf.j2') }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
# validate: "dhcpd -t -cf %s"
notify: Restart dhcpd
+- name: Create leases file
+ ansible.builtin.copy:
+ dest: /var/db/isc-dhcp/dhcpd.leases
+ content: ""
+ mode: "0644"
+ owner: _isc-dhcp
+ group: _isc-dhcp
+ force: false
+ when: ansible_os_family == "OpenBSD"
+
- name: Enable service
ansible.builtin.service:
name: "{{ dhcpd_service }}"
diff --git a/roles/dhcpd/templates/dhcpd.conf.cam.j2 b/roles/dhcpd/templates/dhcpd.conf.cam.j2
index edddc1a..54eff12 100644
--- a/roles/dhcpd/templates/dhcpd.conf.cam.j2
+++ b/roles/dhcpd/templates/dhcpd.conf.cam.j2
@@ -29,10 +29,12 @@ shared-network CAMNET {
use-host-decl-names on;
}
- host ipcam01.cam.foo.sh {
- option host-name "ipcam01.cam.foo.sh";
- hardware ethernet ec:71:db:6e:bc:0f;
- fixed-address 172.20.26.101;
+{% for host in ldap_hosts.results %}
+ host {{ host['cn'] }} {
+ option host-name "{{ host['cn'] }}";
+ hardware ethernet {{ host['macAddress'] }};
+ fixed-address {{ host['ipHostNumber'] }};
}
+{% endfor %}
}
diff --git a/roles/dhcpd/templates/dhcpd.conf.j2 b/roles/dhcpd/templates/dhcpd.conf.j2
index 063a27f..7b41b05 100644
--- a/roles/dhcpd/templates/dhcpd.conf.j2
+++ b/roles/dhcpd/templates/dhcpd.conf.j2
@@ -52,7 +52,7 @@ shared-network FOOSH {
option routers 172.20.20.1;
option domain-name "home.foo.sh";
- option domain-name-servers 172.20.20.10, 172.20.21.1, 172.20.21.2;
+ option domain-name-servers 172.20.20.10, 172.20.20.11, 172.20.20.12;
use-host-decl-names on;
}
diff --git a/roles/dhcpd/templates/dhcpd.conf.oob.j2 b/roles/dhcpd/templates/dhcpd.conf.oob.j2
new file mode 100644
index 0000000..b1a9034
--- /dev/null
+++ b/roles/dhcpd/templates/dhcpd.conf.oob.j2
@@ -0,0 +1,40 @@
+
+authorative;
+ddns-update-style none;
+
+# logging
+on commit {
+ log(info,
+ concat("Client ",
+ binary-to-ascii(16, 8, ":", substring(hardware, 1, 6)),
+ " requests ",
+ binary-to-ascii(16, 8, ":", option dhcp-parameter-request-list),
+ " - ",
+ pick-first-value(option vendor-class-identifier, "no vendor-id"),
+ " - ",
+ pick-first-value(option user-class, "no user-class"))
+ );
+}
+
+shared-network OOBNET {
+
+ subnet 172.20.25.0 netmask 255.255.255.0 {
+ default-lease-time 86400;
+ max-lease-time 604800;
+ option subnet-mask 255.255.255.0;
+ option broadcast-address 172.20.25.255;
+
+ option domain-name "oob.foo.sh";
+ option domain-name-servers 172.20.25.1, 172.20.25.2, 172.20.25.3;
+ use-host-decl-names on;
+ }
+
+{% for host in ldap_hosts.results %}
+ host {{ host['cn'] }} {
+ option host-name "{{ host['cn'] }}";
+ hardware ethernet {{ host['macAddress'] }};
+ fixed-address {{ host['ipHostNumber'] }};
+ }
+{% endfor %}
+
+}
diff --git a/roles/dhcpd/templates/dhcpd.conf.print.j2 b/roles/dhcpd/templates/dhcpd.conf.print.j2
index ca0ab35..da5c2e7 100644
--- a/roles/dhcpd/templates/dhcpd.conf.print.j2
+++ b/roles/dhcpd/templates/dhcpd.conf.print.j2
@@ -29,10 +29,12 @@ shared-network PRINTNET {
use-host-decl-names on;
}
- host hp1.print.foo.sh {
- option host-name "hp1.print.foo.sh";
- hardware ethernet 00:15:99:22:79:46;
- fixed-address 172.20.24.101;
+{% for host in ldap_hosts.results %}
+ host {{ host['cn'] }} {
+ option host-name "{{ host['cn'] }}";
+ hardware ethernet {{ host['macAddress'] }};
+ fixed-address {{ host['ipHostNumber'] }};
}
+{% endfor %}
}
diff --git a/roles/dhparams/tasks/main.yml b/roles/dhparams/tasks/main.yml
index e871137..74ce0bf 100644
--- a/roles/dhparams/tasks/main.yml
+++ b/roles/dhparams/tasks/main.yml
@@ -4,6 +4,6 @@
ansible.builtin.copy:
dest: "{{ tls_certs }}/ffdhe3072.pem"
src: ffdhe3072.pem
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml
index d1f4b05..cc4b9b1 100644
--- a/roles/docker/tasks/main.yml
+++ b/roles/docker/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.get_url:
url: "https://download.docker.com/linux/{{ docker_osname }}/docker-ce.repo"
dest: /etc/yum.repos.d/docker-ce.repo
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -12,17 +12,11 @@
name: docker-ce
state: installed
-- name: Enable user namespaces
- ansible.posix.sysctl:
- name: user.max_user_namespaces
- value: "10240"
- sysctl_file: /etc/sysctl.d/00-docker.conf
-
- name: Create config directory
ansible.builtin.file:
path: /etc/docker
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -30,7 +24,7 @@
ansible.builtin.copy:
dest: /etc/docker/daemon.json
src: daemon.json
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart docker
diff --git a/roles/docker_distribution/tasks/main.yml b/roles/docker_distribution/tasks/main.yml
index 07c6c8b..cf85697 100644
--- a/roles/docker_distribution/tasks/main.yml
+++ b/roles/docker_distribution/tasks/main.yml
@@ -7,7 +7,7 @@
- name: Create docker group
ansible.builtin.group:
name: docker
- gid: 1004
+ gid: 311
- name: Create docker user
ansible.builtin.user:
@@ -18,13 +18,13 @@
groups: hostkey
home: /var/empty
shell: /sbin/nologin
- uid: 1004
+ uid: 311
- name: Create unit file drop-in directory
ansible.builtin.file:
path: /etc/systemd/system/docker-distribution.service.d
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -32,7 +32,7 @@
ansible.builtin.copy:
dest: /etc/systemd/system/docker-distribution.service.d/user.conf
src: user.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart docker-distribution
@@ -41,7 +41,7 @@
ansible.builtin.template:
dest: /etc/docker-distribution/registry/config.yml
src: config.yml.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart docker-distribution
@@ -50,7 +50,7 @@
ansible.builtin.file:
path: /srv/registry/docker
state: directory
- mode: 0770
+ mode: "0770"
owner: root
group: docker
@@ -58,7 +58,7 @@
ansible.builtin.copy:
dest: /etc/docker-distribution/registry/htpasswd
src: "{{ htpasswd }}"
- mode: 0640
+ mode: "0640"
owner: root
group: docker
when: htpasswd is defined
diff --git a/roles/dovecot/tasks/main.yml b/roles/dovecot/tasks/main.yml
index 01f9116..06932b1 100644
--- a/roles/dovecot/tasks/main.yml
+++ b/roles/dovecot/tasks/main.yml
@@ -8,16 +8,16 @@
ansible.builtin.include_role:
name: keytab
vars:
- keytab: /etc/dovecot/dovecot.keytab
- principals:
+ keytab_path: /etc/dovecot/dovecot.keytab
+ keytab_principals:
- "imap/{{ mail_server }}@{{ kerberos_realm }}"
- group: dovecot
+ keytab_group: dovecot
- name: Install privatekey
ansible.builtin.copy:
dest: "{{ tls_private }}/{{ mail_server }}.key"
src: "{{ item }}"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
with_first_found:
@@ -30,7 +30,7 @@
ansible.builtin.copy:
dest: "{{ tls_certs }}/{{ mail_server }}-fullchain.crt"
src: "{{ item }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
with_first_found:
@@ -43,7 +43,7 @@
ansible.builtin.template:
dest: /etc/dovecot/conf.d/99-local.conf
src: local.conf.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
validate: doveconf -n %s
@@ -58,7 +58,7 @@
ansible.builtin.file:
path: "{{ item }}"
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
setype: _default
diff --git a/roles/dovecot/templates/local.conf.j2 b/roles/dovecot/templates/local.conf.j2
index 730072b..6276c88 100644
--- a/roles/dovecot/templates/local.conf.j2
+++ b/roles/dovecot/templates/local.conf.j2
@@ -1,14 +1,13 @@
-# https://ssl-config.mozilla.org/#server=dovecot&version=2.3.8&config=intermediate&openssl=1.1.1g&guideline=5.6
+# generated 2024-12-15, Mozilla Guideline v5.7, Dovecot 2.3.16, OpenSSL 3.2.2, modern config
+# https://ssl-config.mozilla.org/#server=dovecot&version=2.3.16&config=modern&openssl=3.2.2&guideline=5.7
ssl = required
ssl_cert = <{{ tls_certs }}/{{ mail_server }}-fullchain.crt
ssl_key = <{{ tls_private }}/{{ mail_server }}.key
-ssl_dh = <{{ tls_certs }}/ffdhe3072.pem
-
-ssl_min_protocol = TLSv1.2
-ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+ssl_min_protocol = TLSv1.3
ssl_prefer_server_ciphers = no
+ssl_curve_list = X25519:prime256v1:secp384r1
# kerberos
auth_gssapi_hostname = "$ALL"
diff --git a/roles/forgejo/defaults/main.yml b/roles/forgejo/defaults/main.yml
new file mode 100644
index 0000000..848f7a1
--- /dev/null
+++ b/roles/forgejo/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+forgejo_url: >-
+ {{
+ "https://codeberg.org/forgejo/forgejo/releases/download/v" +
+ forgejo_version + "/forgejo-" + forgejo_version + "-" +
+ ansible_system | lower + "-amd64"
+ }}
diff --git a/roles/forgejo/files/forgejo.service b/roles/forgejo/files/forgejo.service
new file mode 100644
index 0000000..289ccdc
--- /dev/null
+++ b/roles/forgejo/files/forgejo.service
@@ -0,0 +1,16 @@
+[Unit]
+Description=Forgejo (Beyond coding. We forge.)
+After=syslog.target
+After=network.target
+
+[Service]
+Type=simple
+User=forgejo
+Group=forgejo
+WorkingDirectory=/srv/forgejo
+ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
+Restart=always
+Environment=HOME=/srv/forgejo FORGEJO_WORK_DIR=/srv/forgejo
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/zoneminder/handlers/main.yml b/roles/forgejo/handlers/main.yml
similarity index 52%
rename from roles/zoneminder/handlers/main.yml
rename to roles/forgejo/handlers/main.yml
index d34c003..4b650b4 100644
--- a/roles/zoneminder/handlers/main.yml
+++ b/roles/forgejo/handlers/main.yml
@@ -1,5 +1,5 @@
---
-- name: Restart zoneminder
+- name: Restart forgejo
ansible.builtin.service:
- name: zoneminder
+ name: forgejo
state: restarted
diff --git a/roles/gitea_runner/meta/main.yml b/roles/forgejo/meta/main.yml
similarity index 64%
rename from roles/gitea_runner/meta/main.yml
rename to roles/forgejo/meta/main.yml
index 4dfd1ac..d5e8ce4 100644
--- a/roles/gitea_runner/meta/main.yml
+++ b/roles/forgejo/meta/main.yml
@@ -1,4 +1,4 @@
---
dependencies:
- - {role: docker}
- {role: git}
+ - {role: nginx}
diff --git a/roles/gitea/tasks/main.yml b/roles/forgejo/tasks/main.yml
similarity index 51%
rename from roles/gitea/tasks/main.yml
rename to roles/forgejo/tasks/main.yml
index 208eed0..4b8c6f2 100644
--- a/roles/gitea/tasks/main.yml
+++ b/roles/forgejo/tasks/main.yml
@@ -1,79 +1,84 @@
---
+- name: Install dependencies
+ ansible.builtin.package:
+ name: git-lfs
+ state: installed
+
- name: Download binary
ansible.builtin.get_url:
- url: "{{ gitea_url }}"
- checksum: "sha256:{{ gitea_url }}.sha256"
- dest: /usr/local/bin/gitea
- mode: 0755
+ url: "{{ forgejo_url }}"
+ checksum: "sha256:{{ forgejo_url }}.sha256"
+ dest: /usr/local/bin/forgejo
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
- notify: Restart gitea
+ notify: Restart forgejo
- name: Create group
ansible.builtin.group:
- name: gitea
+ name: forgejo
gid: 303
- name: Create user
ansible.builtin.user:
- name: gitea
- comment: Service Gitea
+ name: forgejo
+ comment: Service Forgejo
createhome: false
- group: gitea
+ group: forgejo
home: /var/empty
shell: /sbin/nologin
uid: 303
- name: Create config directory
ansible.builtin.file:
- path: /etc/gitea
+ path: /etc/forgejo
state: directory
- mode: 0750
+ mode: "0750"
owner: root
- group: gitea
+ group: forgejo
- name: Create config
ansible.builtin.template:
- dest: /etc/gitea/app.ini
+ dest: /etc/forgejo/app.ini
src: app.ini.j2
- mode: 0640
+ mode: "0640"
owner: root
- group: gitea
- notify: Restart gitea
+ group: forgejo
+ notify: Restart forgejo
- name: Create data directory
ansible.builtin.file:
- path: /export/gitea
+ path: /export/forgejo
state: directory
- mode: 0750
- owner: gitea
- group: gitea
+ mode: "0750"
+ owner: forgejo
+ group: forgejo
- name: Link data directory
ansible.builtin.file:
- path: /srv/gitea
+ path: /srv/forgejo
state: link
- src: /export/gitea
+ src: /export/forgejo
owner: root
group: "{{ ansible_wheel }}"
follow: false
- name: Create service file
ansible.builtin.copy:
- dest: /etc/systemd/system/gitea.service
- src: gitea.service
- mode: 0644
+ dest: /etc/systemd/system/forgejo.service
+ src: forgejo.service
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
- notify: Restart gitea
+ notify: Restart forgejo
- name: Enable service
ansible.builtin.service:
- name: gitea
+ name: forgejo
state: started
enabled: true
-- name: Allow nginx to connect gitea
+- name: Allow nginx to connect forgejo
ansible.posix.seboolean:
name: httpd_can_network_connect
state: true
@@ -81,19 +86,22 @@
- name: Copy nginx config
ansible.builtin.copy:
- dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/gitea.conf"
+ dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/forgejo.conf"
content: |
+ client_max_body_size 100m;
location / {
proxy_pass http://127.0.0.1:3000;
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
-- name: Add gitea alias for root
+- name: Add forgejo alias for root
ansible.builtin.blockinfile:
- path: /root/.bash_profile
+ path: /root/.bashrc
block: |
- # run gitea as gitea user
- alias gitea='sudo -u gitea HOME=/srv/gitea GITEA_WORK_DIR=/srv/gitea /usr/local/bin/gitea -c /etc/gitea/app.ini'
+ # run forgejo as forgejo user
+ alias forgejo='sudo -u forgejo HOME=/srv/forgejo \
+ GITEA_WORK_DIR=/srv/forgejo \
+ /usr/local/bin/forgejo -c /etc/forgejo/app.ini'
diff --git a/roles/gitea/templates/app.ini.j2 b/roles/forgejo/templates/app.ini.j2
similarity index 76%
rename from roles/gitea/templates/app.ini.j2
rename to roles/forgejo/templates/app.ini.j2
index 9ce2612..a8a7716 100644
--- a/roles/gitea/templates/app.ini.j2
+++ b/roles/forgejo/templates/app.ini.j2
@@ -1,21 +1,21 @@
APP_NAME = foo.sh - GIT
-RUN_USER = gitea
+RUN_USER = forgejo
RUN_MODE = prod
[database]
DB_TYPE = mysql
HOST = sqldb02.home.foo.sh
-NAME = gitea
-USER = gitea
-PASSWD = {{ gitea_mysql_pass }}
+NAME = forgejo
+USER = forgejo
+PASSWD = {{ forgejo_mysql_pass }}
SCHEMA =
SSL_MODE = true
CHARSET = utf8
-PATH = /srv/gitea/data/gitea.db
+PATH = /srv/forgejo/data/forgejo.db
LOG_SQL = false
[repository]
-ROOT = /srv/gitea/data/gitea-repositories
+ROOT = /srv/forgejo/data/forgejo-repositories
[server]
SSH_DOMAIN = localhost
@@ -26,11 +26,11 @@ ROOT_URL = https://git.foo.sh/
DISABLE_SSH = true
SSH_PORT = 22
LFS_START_SERVER = true
-LFS_JWT_SECRET = {{ gitea_lfs_jwt_secret }}
+LFS_JWT_SECRET = {{ forgejo_lfs_jwt_secret }}
OFFLINE_MODE = false
[lfs]
-PATH = /srv/gitea/data/lfs
+PATH = /srv/forgejo/data/lfs
[mailer]
ENABLED = false
@@ -57,8 +57,6 @@ PROVIDER = file
[log]
MODE = console
LEVEL = info
-ROOT_PATH = /srv/gitea/log
-ROUTER = console
[repository.pull-request]
DEFAULT_MERGE_STYLE = merge
@@ -68,10 +66,13 @@ DEFAULT_TRUST_MODEL = committer
[security]
INSTALL_LOCK = true
-INTERNAL_TOKEN = {{ gitea_internal_token }}
+INTERNAL_TOKEN = {{ forgejo_internal_token }}
PASSWORD_HASH_ALGO = pbkdf2
REVERSE_PROXY_TRUSTED_PROXIES = 127.0.0.0/8,::1/128
REVERSE_PROXY_LIMIT = 1
[actions]
ENABLED = true
+
+[oauth2]
+JWT_SECRET = {{ forgejo_oauth_jwt_secret }}
diff --git a/roles/frigate/defaults/main.yml b/roles/frigate/defaults/main.yml
new file mode 100644
index 0000000..3266cf2
--- /dev/null
+++ b/roles/frigate/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+frigate_version: stable
diff --git a/roles/frigate/files/99-frigate.rules b/roles/frigate/files/99-frigate.rules
new file mode 100644
index 0000000..9d5516e
--- /dev/null
+++ b/roles/frigate/files/99-frigate.rules
@@ -0,0 +1,2 @@
+SUBSYSTEM=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="9302", MODE="0660", GROUP="frigate"
+SUBSYSTEM=="usb", ATTRS{idVendor}=="1a6e", ATTRS{idProduct}=="089a", MODE="0660", GROUP="frigate"
diff --git a/roles/frigate/handlers/main.yml b/roles/frigate/handlers/main.yml
new file mode 100644
index 0000000..9b0555a
--- /dev/null
+++ b/roles/frigate/handlers/main.yml
@@ -0,0 +1,12 @@
+---
+- name: Clear preview restart cache
+ ansible.builtin.file:
+ path: /srv/frigate/media/clips/preview_restart_cache
+ state: absent
+ listen: Restart frigate
+
+- name: Restart frigate
+ ansible.builtin.systemd_service:
+ name: frigate-container
+ state: restarted
+ daemon_reload: true
diff --git a/roles/frigate/meta/main.yml b/roles/frigate/meta/main.yml
new file mode 100644
index 0000000..9699a03
--- /dev/null
+++ b/roles/frigate/meta/main.yml
@@ -0,0 +1,5 @@
+---
+dependencies:
+ - {role: apache}
+ - {role: podman}
+ - {role: udev}
diff --git a/roles/frigate/tasks/main.yml b/roles/frigate/tasks/main.yml
new file mode 100644
index 0000000..7401e1f
--- /dev/null
+++ b/roles/frigate/tasks/main.yml
@@ -0,0 +1,153 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: frigate
+
+- name: Create user
+ ansible.builtin.user:
+ name: frigate
+ comment: Podman Frigate
+ group: frigate
+ shell: /sbin/nologin
+
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - frigate
+ creates: /var/lib/systemd/linger/frigate
+
+- name: Allow podman to use devices
+ ansible.posix.seboolean:
+ name: container_use_devices
+ state: true
+ persistent: true
+
+- name: Allow frigate to connect specific devices
+ ansible.builtin.copy:
+ dest: /etc/udev/rules.d/99-frigate.rules
+ src: 99-frigate.rules
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Reload udev rules
+
+- name: Copy host key
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/frigate.key"
+ src: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ mode: "0640"
+ owner: root
+ group: frigate
+ remote_src: true
+ notify: Restart frigate
+
+- name: Get cameras from LDAP
+ community.general.ldap_search:
+ attrs:
+ - cn
+ - l
+ client_cert: >-
+ {{ hostvars[ansible_server]['tls_certs'] + '/' + ansible_server }}.crt
+ client_key: >-
+ {{ hostvars[ansible_server]['tls_private'] + '/' + ansible_server }}.key
+ dn: "{{ ldap_basedn }}"
+ filter: (&(objectClass=ipHost)(cn=ipcam*.cam.foo.sh))
+ scope: subordinate
+ server_uri: "ldaps://{{ ldap_server[0] }}"
+ delegate_to: localhost
+ register: ldap_cams
+
+- name: Create config
+ ansible.builtin.template:
+ dest: /etc/frigate.yml
+ src: frigate.yml.j2
+ mode: "0640"
+ owner: root
+ group: frigate
+ notify: Restart frigate
+
+- name: Fix SELinux contexts from data directory
+ community.general.sefcontext:
+ path: /export/frigate(/.*)?
+ setype: container_file_t
+ when: ansible_selinux_python_present
+
+- name: Create base directory
+ ansible.builtin.file:
+ path: /export/frigate
+ state: directory
+ mode: "0755"
+ owner: root
+ group: root
+ setype: _default
+
+- name: Create data directories
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: directory
+ mode: "0770"
+ owner: root
+ group: frigate
+ setype: _default
+ with_items:
+ - /export/frigate/config
+ - /export/frigate/media
+
+- name: Link data directory
+ ansible.builtin.file:
+ dest: /srv/frigate
+ src: /export/frigate
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+
+- name: Create service file
+ ansible.builtin.template:
+ dest: /etc/systemd/system/frigate-container.service
+ src: frigate-container.service.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart frigate
+
+- name: Create environment config for service
+ ansible.builtin.template:
+ dest: /etc/sysconfig/frigate-container
+ src: frigate-container.sysconfig.j2
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart frigate
+
+- name: Enable service
+ ansible.builtin.service:
+ name: frigate-container
+ state: started
+ enabled: true
+
+- name: Copy apache config
+ ansible.builtin.copy:
+ dest: /etc/httpd/conf.local.d/frigate-container.conf
+ content: |
+ ProxyPass /frigate/ http://127.0.0.1:8007/
+ ProxyPassReverse /frigate/ http://127.0.0.1:8007/
+
+ ProxyPass /frigate/ws ws://127.0.0.1:8007/ws
+ ProxyPassReverse /frigate/ws ws://127.0.0.1:8007/ws
+
+ ProxyPass /frigate/live ws://127.0.0.1:8007/live
+ ProxyPassReverse /frigate/live ws://127.0.0.1:8007/live
+
+
+ RewriteEngine on
+ RewriteCond %{HTTP:Upgrade} =websocket [NC]
+ RewriteRule /(.*) ws://127.0.0.1:8007/$1 [P,L]
+ RewriteCond %{HTTP:Upgrade} !=websocket [NC]
+ RewriteRule /(.*) http://127.0.0.1:8007/$1 [P,L]
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart apache
diff --git a/roles/frigate/templates/frigate-container.service.j2 b/roles/frigate/templates/frigate-container.service.j2
new file mode 100644
index 0000000..8766bb6
--- /dev/null
+++ b/roles/frigate/templates/frigate-container.service.j2
@@ -0,0 +1,25 @@
+[Unit]
+Description=Frigate Container
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+User=frigate
+EnvironmentFile=/etc/sysconfig/frigate-container
+ExecStart=/usr/bin/podman run \
+ --rm -p 127.0.0.1:8007:5000 \
+ --name frigate \
+ --volume {{ tls_certs }}/ca.crt:/etc/ssl/certs/ca.crt:ro \
+ --volume {{ tls_certs }}/{{ inventory_hostname }}.crt:/etc/ssl/certs/{{ inventory_hostname }}.crt:ro \
+ --volume {{ tls_private }}/frigate.key:/etc/ssl/private/{{ inventory_hostname }}.key:ro \
+ --volume /srv/frigate/config:/config:rw \
+ --volume /etc/frigate.yml:/config/config.yml:ro \
+ --volume /srv/frigate/media:/media/frigate:rw \
+ --volume /dev/bus/usb:/dev/bus/usb:rw \
+ --shm-size 1024M \
+ --env=FRIGATE_* ghcr.io/blakeblackshear/frigate:{{ frigate_version }}
+ExecStop=/usr/bin/podman stop --ignore frigate
+ExecStopPost=/usr/bin/podman rm -f --ignore frigate
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/frigate/templates/frigate-container.sysconfig.j2 b/roles/frigate/templates/frigate-container.sysconfig.j2
new file mode 100644
index 0000000..1f9f038
--- /dev/null
+++ b/roles/frigate/templates/frigate-container.sysconfig.j2
@@ -0,0 +1,3 @@
+{% for camera in ldap_cams.results %}
+FRIGATE_{{ camera['l'] | upper }}_PASS="{{ cctv_cameras[camera['cn']] }}"
+{% endfor %}
diff --git a/roles/frigate/templates/frigate.yml.j2 b/roles/frigate/templates/frigate.yml.j2
new file mode 100644
index 0000000..c269f6d
--- /dev/null
+++ b/roles/frigate/templates/frigate.yml.j2
@@ -0,0 +1,41 @@
+---
+mqtt:
+ enabled: true
+ host: mqtt02.home.foo.sh
+ port: 8883
+ topic_prefix: frigate/{{ inventory_hostname }}
+ client_id: {{ inventory_hostname }}
+ tls_ca_certs: /etc/ssl/certs/ca.crt
+ tls_client_cert: /etc/ssl/certs/{{ inventory_hostname }}.crt
+ tls_client_key: /etc/ssl/private/{{ inventory_hostname }}.key
+
+detectors:
+ coral:
+ type: edgetpu
+ device: usb
+
+record:
+ enabled: true
+ retain:
+ days: 7
+ mode: motion
+ detections:
+ retain:
+ days: 30
+ mode: motion
+
+cameras:
+{% for camera in ldap_cams.results %}
+ {{ camera['l'] }}:
+ enabled: true
+ ffmpeg:
+ inputs:
+ - path: "rtsp://viewer:{FRIGATE_{{ camera['l'] | upper }}_PASS}@{{ camera['cn'] }}/h264Preview_01_sub"
+ input_args: preset-rtsp-restream
+ roles:
+ - detect
+ - path: "rtsp://viewer:{FRIGATE_{{ camera['l'] | upper }}_PASS}@{{ camera['cn'] }}/h264Preview_01_main"
+ input_args: preset-rtsp-restream
+ roles:
+ - record
+{% endfor %}
diff --git a/roles/fwupd/tasks/main.yml b/roles/fwupd/tasks/main.yml
new file mode 100644
index 0000000..5e71293
--- /dev/null
+++ b/roles/fwupd/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: fwupd
+ state: installed
+
+- name: Enable LVFS
+ ansible.builtin.lineinfile:
+ path: /etc/fwupd/remotes.d/lvfs.conf
+ regexp: "^Enabled=.*"
+ line: "Enabled=true"
diff --git a/roles/git_server/tasks/main.yml b/roles/git_server/tasks/main.yml
index 889897c..2e22a61 100644
--- a/roles/git_server/tasks/main.yml
+++ b/roles/git_server/tasks/main.yml
@@ -17,7 +17,7 @@
ansible.builtin.file:
path: /export/git
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -33,7 +33,7 @@
ansible.builtin.copy:
dest: /etc/gitweb.conf
src: gitweb.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -41,7 +41,7 @@
ansible.builtin.copy:
dest: /var/www/git/robots.txt
content: "User-agent: *\nDisallow:\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -49,7 +49,7 @@
ansible.builtin.copy:
dest: "/var/www/git/static/{{ item }}"
src: "{{ item }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
with_items:
@@ -60,7 +60,7 @@
ansible.builtin.copy:
dest: /etc/httpd/conf.local.d/git.conf
src: git.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
diff --git a/roles/gitea/defaults/main.yml b/roles/gitea/defaults/main.yml
deleted file mode 100644
index 6a37123..0000000
--- a/roles/gitea/defaults/main.yml
+++ /dev/null
@@ -1,2 +0,0 @@
----
-gitea_url: "https://dl.gitea.com/gitea/{{ gitea_version }}/gitea-{{ gitea_version }}-{{ ansible_system | lower }}-amd64"
diff --git a/roles/gitea/files/gitea.service b/roles/gitea/files/gitea.service
deleted file mode 100644
index 0dfec4a..0000000
--- a/roles/gitea/files/gitea.service
+++ /dev/null
@@ -1,16 +0,0 @@
-[Unit]
-Description=Gitea (Git with a cup of tea)
-After=syslog.target
-After=network.target
-
-[Service]
-Type=simple
-User=gitea
-Group=gitea
-WorkingDirectory=/srv/gitea
-ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
-Restart=always
-Environment=HOME=/srv/gitea GITEA_WORK_DIR=/srv/gitea
-
-[Install]
-WantedBy=multi-user.target
diff --git a/roles/gitea/meta/main.yml b/roles/gitea/meta/main.yml
deleted file mode 100644
index f9c5d0d..0000000
--- a/roles/gitea/meta/main.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-dependencies:
- - {role: git}
- - {role: nginx/server}
diff --git a/roles/gitea_runner/defaults/main.yml b/roles/gitea_runner/defaults/main.yml
deleted file mode 100644
index bb9e11e..0000000
--- a/roles/gitea_runner/defaults/main.yml
+++ /dev/null
@@ -1,2 +0,0 @@
----
-gitea_runner_version: main
diff --git a/roles/gitea_runner/files/act_runner.service b/roles/gitea_runner/files/act_runner.service
deleted file mode 100644
index 1533c88..0000000
--- a/roles/gitea_runner/files/act_runner.service
+++ /dev/null
@@ -1,14 +0,0 @@
-[Unit]
-Description=Act Runner for Gitea
-After=syslog.target
-After=network.target
-
-[Service]
-User=act_runner
-Group=act_runner
-WorkingDirectory=/var/lib/act_runner
-Environment=HOME=/var/lib/act_runner
-ExecStart=/usr/local/bin/act_runner daemon -c /var/lib/act_runner/config.yml
-
-[Install]
-WantedBy=multi-user.target
diff --git a/roles/gitea_runner/files/config.yml b/roles/gitea_runner/files/config.yml
deleted file mode 100644
index bd7abba..0000000
--- a/roles/gitea_runner/files/config.yml
+++ /dev/null
@@ -1,50 +0,0 @@
----
-log:
- # The level of logging, can be trace, debug, info, warn, error, fatal
- level: info
-
-runner:
- # Where to store the registration result.
- file: .runner
- # Execute how many tasks concurrently at the same time.
- capacity: 1
- # Extra environment variables to run jobs from a file.
- # It will be ignored if it's empty or the file doesn't exist.
- env_file: .env
- # The timeout for a job to be finished.
- # Please note that the Gitea instance also has a timeout (3h by default)
- # for the job. So the job could be stopped by the Gitea instance if it's
- # timeout is shorter than this.
- timeout: 3h
- # Whether skip verifying the TLS certificate of the Gitea instance.
- insecure: false
- # The timeout for fetching the job from the Gitea instance.
- fetch_timeout: 5s
- # The interval for fetching the job from the Gitea instance.
- fetch_interval: 2s
-
-cache:
- # Enable cache server to use actions/cache.
- enabled: true
- # The directory to store the cache data.
- # If it's empty, the cache data will be stored in $HOME/.cache/actcache.
- dir: ""
- # The host of the cache server.
- # It's not for the address to listen, but the address to connect from job
- # containers. So 0.0.0.0 is a bad choice, leave it empty to detect
- # automatically.
- host: ""
- # The port of the cache server.
- # 0 means to use a random available port.
- port: 0
-
-container:
- # Which network to use for the job containers. Could be bridge, host, none,
- # or the name of a custom network.
- network_mode: bridge
- # Whether to use privileged mode or not when launching task containers
- # (privileged mode is required for Docker-in-Docker).
- privileged: false
- # And other options to be used when the container is started
- # (eg, --add-host=my.gitea.url:host-gateway).
- options:
diff --git a/roles/gitea_runner/tasks/main.yml b/roles/gitea_runner/tasks/main.yml
deleted file mode 100644
index 740a914..0000000
--- a/roles/gitea_runner/tasks/main.yml
+++ /dev/null
@@ -1,85 +0,0 @@
----
-- name: Create group
- ansible.builtin.group:
- name: act_runner
- system: true
-
-- name: Create user
- ansible.builtin.user:
- name: act_runner
- system: true
- comment: Gitea act_runner
- create_home: false
- home: /var/empty
- group: act_runner
- groups:
- - docker
- shell: /sbin/nologin
-
-- name: Install dependencies
- ansible.builtin.package:
- name: golang
- state: installed
-
-- name: Download binary
- ansible.builtin.get_url:
- url: >
- {{
- "https://gitea.com/gitea/act_runner/releases/download/v" +
- gitea_runner_version + "/act_runner-" + gitea_runner_version +
- "-" + ansible_system | lower + "-amd64"
- }}
- dest: /usr/local/bin/act_runner
- mode: 0755
- owner: root
- group: "{{ ansible_wheel }}"
- notify: Restart act_runner
-
-- name: Create config directory
- ansible.builtin.file:
- path: /var/lib/act_runner
- state: directory
- mode: 0750
- owner: root
- group: act_runner
-
-- name: Copy config file
- ansible.builtin.copy:
- dest: /var/lib/act_runner/.runner
- src: "/srv/private/files/act_runner/{{ inventory_hostname }}.conf"
- mode: 0640
- owner: root
- group: act_runner
- notify: Restart act_runner
-
-- name: Copy config file
- ansible.builtin.copy:
- dest: /var/lib/act_runner/config.yml
- src: config.yml
- mode: 0640
- owner: root
- group: act_runner
- notify: Restart act_runner
-
-- name: Create cache directory
- ansible.builtin.file:
- path: /var/lib/act_runner/.cache
- state: directory
- mode: 0770
- owner: root
- group: act_runner
- notify: Restart act_runner
-
-- name: Copy unit file
- ansible.builtin.copy:
- dest: /etc/systemd/system/act_runner.service
- src: act_runner.service
- mode: 0644
- owner: root
- group: root
-
-- name: Enable service
- ansible.builtin.service:
- name: act_runner
- state: started
- enabled: true
diff --git a/roles/google_spell_pspell/files/google-spell-pspell-container.service b/roles/google_spell_pspell/files/google-spell-pspell-container.service
new file mode 100644
index 0000000..705ff29
--- /dev/null
+++ b/roles/google_spell_pspell/files/google-spell-pspell-container.service
@@ -0,0 +1,16 @@
+[Unit]
+Description=google-spell-pspell Container
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+User=pspell
+ExecStart=/usr/bin/podman run \
+ --rm -p 127.0.0.1:8010:80 \
+ --name google-spell-pspell \
+ google-spell-pspell:latest
+ExecStop=/usr/bin/podman stop --ignore google-spell-pspell
+ExecStopPost=/usr/bin/podman rm -f --ignore google-spell-pspell
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/google_spell_pspell/handlers/main.yml b/roles/google_spell_pspell/handlers/main.yml
new file mode 100644
index 0000000..c6f29db
--- /dev/null
+++ b/roles/google_spell_pspell/handlers/main.yml
@@ -0,0 +1,18 @@
+---
+- name: Rebuild google-spell-pspell-container
+ ansible.builtin.command:
+ argv:
+ - podman
+ - build
+ - -t
+ - google-spell-pspell
+ - /usr/local/src/docker-google-spell-pspell
+ become: true
+ become_user: pspell
+ notify: Restart google-spell-pspell-container
+
+- name: Restart google-spell-pspell-container
+ ansible.builtin.service:
+ name: google-spell-pspell-container
+ daemon_reload: true
+ state: restarted
diff --git a/roles/google_spell_pspell/meta/main.yml b/roles/google_spell_pspell/meta/main.yml
new file mode 100644
index 0000000..b8e2a3e
--- /dev/null
+++ b/roles/google_spell_pspell/meta/main.yml
@@ -0,0 +1,5 @@
+---
+dependencies:
+ - {role: git}
+ - {role: nginx}
+ - {role: podman}
diff --git a/roles/google_spell_pspell/tasks/main.yml b/roles/google_spell_pspell/tasks/main.yml
new file mode 100644
index 0000000..2fe09ee
--- /dev/null
+++ b/roles/google_spell_pspell/tasks/main.yml
@@ -0,0 +1,54 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: pspell
+
+- name: Create user
+ ansible.builtin.user:
+ name: pspell
+ comment: Podman google-spell-pspell
+ group: pspell
+ shell: /sbin/nologin
+
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - pspell
+ creates: /var/lib/systemd/linger/pspell
+
+- name: Get container source
+ ansible.builtin.git:
+ dest: /usr/local/src/docker-google-spell-pspell
+ repo: https://github.com/foo-sh/docker-google-spell-pspell.git
+ update: true
+ version: main
+ notify: Rebuild google-spell-pspell-container
+
+- name: Create service file
+ ansible.builtin.copy:
+ dest: /etc/systemd/system/google-spell-pspell-container.service
+ src: google-spell-pspell-container.service
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart google-spell-pspell-container
+
+- name: Enable service
+ ansible.builtin.service:
+ name: google-spell-pspell-container
+ state: started
+ enabled: true
+
+- name: Copy nginx config
+ ansible.builtin.copy:
+ dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/google-spell-pspell.conf"
+ content: |
+ location /tbproxy/spell {
+ proxy_pass http://127.0.0.1:8010/;
+ }
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
diff --git a/roles/grafana/tasks/main.yml b/roles/grafana/tasks/main.yml
index 3ed3db6..4b59f21 100644
--- a/roles/grafana/tasks/main.yml
+++ b/roles/grafana/tasks/main.yml
@@ -10,11 +10,19 @@
group: grafana
shell: /sbin/nologin
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - grafana
+ creates: /var/lib/systemd/linger/grafana
+
- name: Copy host key
ansible.builtin.copy:
dest: "{{ tls_private }}/grafana.key"
src: "{{ tls_private }}/{{ inventory_hostname }}.key"
- mode: 0640
+ mode: "0640"
owner: root
group: grafana
remote_src: true
@@ -23,7 +31,7 @@
ansible.builtin.template:
dest: /etc/sysconfig/grafana-container
src: grafana-container.sysconfig.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart grafana
@@ -32,7 +40,7 @@
ansible.builtin.template:
dest: /etc/systemd/system/grafana-container.service
src: grafana-container.service.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart grafana
@@ -41,7 +49,7 @@
ansible.builtin.template:
dest: /etc/grafana-ldap.toml
src: grafana-ldap.toml.j2
- mode: 0640
+ mode: "0640"
owner: root
group: grafana
notify: Restart grafana
@@ -58,9 +66,9 @@
content: |
location /grafana/ {
proxy_set_header Host noc.foo.sh;
- proxy_pass http://localhost:8002/;
+ proxy_pass http://127.0.0.1:8002/;
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
diff --git a/roles/grossd/meta/main.yml b/roles/grossd/meta/main.yml
index 7ae8670..50b8afb 100644
--- a/roles/grossd/meta/main.yml
+++ b/roles/grossd/meta/main.yml
@@ -1,3 +1,4 @@
---
dependencies:
+ - {role: crb_repo}
- {role: foosh_repo}
diff --git a/roles/grossd/tasks/main.yml b/roles/grossd/tasks/main.yml
index fe75f97..74079d3 100644
--- a/roles/grossd/tasks/main.yml
+++ b/roles/grossd/tasks/main.yml
@@ -8,7 +8,7 @@
ansible.builtin.file:
path: /var/db/grossd
state: directory
- mode: 0750
+ mode: "0750"
owner: gross
group: "{{ ansible_wheel }}"
@@ -16,7 +16,7 @@
ansible.builtin.copy:
dest: /etc/grossd.conf
src: grossd.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart grossd
diff --git a/roles/ha_mqtt_configd/files/ha_mqtt_configd.py b/roles/ha_mqtt_configd/files/ha_mqtt_configd.py
new file mode 100755
index 0000000..bc1c3e7
--- /dev/null
+++ b/roles/ha_mqtt_configd/files/ha_mqtt_configd.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+
+import hashlib
+import json
+import paho.mqtt.client as mqtt
+import socket
+import ssl
+import syslog
+import time
+
+notify = {}
+
+
+def on_message(client, userdata, msg):
+ if not msg.topic in notify:
+ syslog.syslog(syslog.LOG_INFO, f"Publish config for {msg.topic}")
+ elif notify[msg.topic] < time.monotonic() - 600:
+ syslog.syslog(syslog.LOG_INFO, f"Refresh config for {msg.topic}")
+ else:
+ return
+ topic = msg.topic.split("/")
+ uniqueid = hashlib.md5(msg.topic.encode()).hexdigest()
+ config = {
+ "dev": {
+ "name": topic[2].capitalize(),
+ "suggested_area": topic[1].capitalize().replace("_", " "),
+ "identifiers": [
+ uniqueid,
+ ],
+ },
+ "icon": "mdi:lightning-bolt",
+ "name": "Power Usage",
+ "state_topic": msg.topic,
+ "unit_of_measurement": "W",
+ "unique_id": uniqueid,
+ }
+ client.publish(
+ topic=f"homeassistant/sensor/{uniqueid}/config", payload=json.dumps(config)
+ )
+ notify[msg.topic] = time.monotonic()
+
+
+def connect(hostname):
+ client = mqtt.Client(protocol=mqtt.MQTTv5)
+ client.tls_set(
+ certfile=f"/etc/ssl/{socket.gethostname()}.crt",
+ keyfile=f"/etc/ssl/private/{socket.gethostname()}.key",
+ ca_certs="/etc/ssl/ca.crt",
+ cert_reqs=ssl.CERT_REQUIRED,
+ )
+ client.on_message = on_message
+ client.connect(hostname, 8883)
+ syslog.syslog(syslog.LOG_INFO, f"Connected to MQTT broker {hostname}")
+ return client
+
+
+def main():
+ syslog.openlog(
+ "ha_mqtt_configd", logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON
+ )
+ client = connect(socket.gethostname())
+ try:
+ client.subscribe("home/+/+/power")
+ client.loop_forever()
+ except KeyboardInterrupt:
+ client.disconnect()
+ syslog.closelog()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/roles/ha_mqtt_configd/files/ha_mqtt_configd.rc b/roles/ha_mqtt_configd/files/ha_mqtt_configd.rc
new file mode 100755
index 0000000..dc63988
--- /dev/null
+++ b/roles/ha_mqtt_configd/files/ha_mqtt_configd.rc
@@ -0,0 +1,12 @@
+#!/bin/ksh
+
+daemon="/usr/local/sbin/ha_mqtt_configd"
+daemon_user="ha-mqtt"
+
+. /etc/rc.d/rc.subr
+
+rc_bg=YES
+rc_reload=NO
+pexp="python3 /usr/local/sbin/ha_mqtt_configd"
+
+rc_cmd $1
diff --git a/roles/ha_mqtt_configd/handlers/main.yml b/roles/ha_mqtt_configd/handlers/main.yml
new file mode 100644
index 0000000..79a2cc5
--- /dev/null
+++ b/roles/ha_mqtt_configd/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart ha_mqtt_configd
+ ansible.builtin.service:
+ name: ha_mqtt_configd
+ state: restarted
diff --git a/roles/ha_mqtt_configd/tasks/main.yml b/roles/ha_mqtt_configd/tasks/main.yml
new file mode 100644
index 0000000..0757fa8
--- /dev/null
+++ b/roles/ha_mqtt_configd/tasks/main.yml
@@ -0,0 +1,45 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: py3-paho-mqtt
+ state: installed
+
+- name: Create group
+ ansible.builtin.group:
+ name: ha-mqtt
+ system: true
+
+- name: Create user
+ ansible.builtin.user:
+ name: ha-mqtt
+ comment: ha-mqtt-configd
+ group: ha-mqtt
+ groups: hostkey
+ create_home: false
+ home: /var/empty
+ shell: /sbin/nologin
+ system: true
+
+- name: Copy daemon
+ ansible.builtin.copy:
+ dest: /usr/local/sbin/ha_mqtt_configd
+ src: ha_mqtt_configd.py
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart ha_mqtt_configd
+
+- name: Copy startup script
+ ansible.builtin.copy:
+ dest: /etc/rc.d/ha_mqtt_configd
+ src: ha_mqtt_configd.rc
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart ha_mqtt_configd
+
+- name: Enable service
+ ansible.builtin.service:
+ name: ha_mqtt_configd
+ state: started
+ enabled: true
diff --git a/roles/homeassistant/files/99-homeassistant.rules b/roles/homeassistant/files/99-homeassistant.rules
new file mode 100644
index 0000000..04728a9
--- /dev/null
+++ b/roles/homeassistant/files/99-homeassistant.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE="0660", GROUP="homeassistant"
diff --git a/roles/homeassistant/files/auth-command.py b/roles/homeassistant/files/auth-command.py
new file mode 100755
index 0000000..02fff52
--- /dev/null
+++ b/roles/homeassistant/files/auth-command.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+
+import os
+import re
+import sys
+import requests
+
+username = os.environ.get("username")
+password = os.environ.get("password")
+
+if username is None or password is None:
+ sys.exit(2)
+if not re.search(r"^[a-z]+$", username):
+ sys.exit(2)
+
+resp = requests.post(
+ "https://id.foo.sh/authcheck",
+ json={"username": username, "password": password, "group": "foosh"},
+)
+if resp.status_code != 200:
+ sys.exit(2)
+
+print("name = {}".format(resp.json()["name"]))
+print("group = system-users")
+print("local_only = false")
diff --git a/roles/homeassistant/files/auth-command.sh b/roles/homeassistant/files/auth-command.sh
deleted file mode 100755
index 6b2c2dc..0000000
--- a/roles/homeassistant/files/auth-command.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-set -eu
-
-if [ "$(echo "$username" | sed -r 's/^[a-z]+$/x/')" != "x" ]; then
- exit 2
-fi
-
-curl -sf -X POST -H "Content-Type: application/json" -d @- \
- https://id.foo.sh/authcheck </dev/null 2>&1 || true
+-delgroup "$GROUP" >/dev/null 2>&1 || true
+-
+-# Re-use existing group (can't delgroup a group that is in use)
+-group="$(getent group "$PGID" | cut -d: -f1 || true)"
+-if [ -z "$group" ]; then
+- addgroup -g "$PGID" "$GROUP"
+-else
+- bashio::log.notice "Re-using existing group with gid $PGID: $group"
+- GROUP="$group"
+-fi
+-
+-# Replace existing user (ensures correct shell and primary group)
+-user="$(getent passwd "$PUID" | cut -d: -f1 || true)"
+-if [ -n "$user" ]; then
+- bashio::log.notice "Replacing existing user with uid $PUID: $user"
+- deluser "$user"
+-fi
+-adduser -G "$GROUP" -D -u "$PUID" "$USER"
++if [ "$(whoami)" != "homeassistant" ]; then
+
+-if [ -n "${EXTRA_GID:-}" ]; then
+- bashio::log.info "Resolving supplementary GIDs: $EXTRA_GID"
+- supplementary_groups=()
+-
+- for gid in $EXTRA_GID; do
+- group="$(getent group "$gid" | cut -d: -f1 || true)"
+-
+- if [ -z "$group" ]; then
+- group="$USER-$gid"
+- addgroup -g "$gid" "$group"
+- fi
++ # Some HA commands seem to fail if we don't have an actual user.
++ # ie: shell_command would return error code 255
++ bashio::log.info "Creating user $USER with $PUID:$PGID"
++
++ deluser "$USER" >/dev/null 2>&1 || true
++ delgroup "$GROUP" >/dev/null 2>&1 || true
++
++ # Re-use existing group (can't delgroup a group that is in use)
++ group="$(getent group "$PGID" | cut -d: -f1 || true)"
++ if [ -z "$group" ]; then
++ addgroup -g "$PGID" "$GROUP"
++ else
++ bashio::log.notice "Re-using existing group with gid $PGID: $group"
++ GROUP="$group"
++ fi
+
+- supplementary_groups+=( "$group" )
+- done
++ # Replace existing user (ensures correct shell and primary group)
++ user="$(getent passwd "$PUID" | cut -d: -f1 || true)"
++ if [ -n "$user" ]; then
++ bashio::log.notice "Replacing existing user with uid $PUID: $user"
++ deluser "$user"
++ fi
++ adduser -G "$GROUP" -D -u "$PUID" "$USER"
+
+- bashio::log.info "Appending supplementary groups: ${supplementary_groups[*]}"
+- for group in "${supplementary_groups[@]}"; do
+- addgroup "$USER" "$group"
+- done
++ if [ -n "${EXTRA_GID:-}" ]; then
++ bashio::log.info "Resolving supplementary GIDs: $EXTRA_GID"
++ supplementary_groups=()
++
++ for gid in $EXTRA_GID; do
++ group="$(getent group "$gid" | cut -d: -f1 || true)"
++
++ if [ -z "$group" ]; then
++ group="$USER-$gid"
++ addgroup -g "$gid" "$group"
++ fi
++
++ supplementary_groups+=( "$group" )
++ done
++
++ bashio::log.info "Appending supplementary groups: ${supplementary_groups[*]}"
++ for group in "${supplementary_groups[@]}"; do
++ addgroup "$USER" "$group"
++ done
++ fi
+ fi
+
+ #
+@@ -82,8 +85,12 @@
+ #
+
+ bashio::log.info "Initializing venv in $VENV_PATH"
+-su "$USER" \
+- -c "python3 -m venv --system-site-packages '$VENV_PATH'"
++if [ "$(whoami)" = "homeassistant" ]; then
++ python3 -m venv --system-site-package "$VENV_PATH"
++else
++ su "$USER" \
++ -c "python3 -m venv --system-site-packages '$VENV_PATH'"
++fi
+
+ #
+ # Fix permissions
+@@ -104,8 +111,12 @@
+ export UV_SYSTEM_PYTHON=false
+
+ bashio::log.info "Installing uv into venv"
+-uv --version && su "$USER" \
+- -c "uv pip freeze --system|grep ^uv=|xargs uv pip install"
++if [ "$(whoami)" = "homeassistant" ]; then
++ uv --version && uv pip freeze --system|grep ^uv=|xargs uv pip install
++else
++ uv --version && su "$USER" \
++ -c "uv pip freeze --system|grep ^uv=|xargs uv pip install"
++fi
+
+ bashio::log.info "Setting new \$HOME"
+ HOME="$( getent passwd "$USER" | cut -d: -f6 )"
+@@ -122,6 +133,10 @@
+ fi
+
+ bashio::log.info "Starting homeassistant"
+-exec \
+- s6-setuidgid "$USER" \
+- python3 -m homeassistant --config "$CONFIG_PATH"
++if [ "$(whoami)" = "homeassistant" ]; then
++ exec python3 -m homeassistant --config "$CONFIG_PATH"
++else
++ exec \
++ s6-setuidgid "$USER" \
++ python3 -m homeassistant --config "$CONFIG_PATH"
++fi
diff --git a/roles/homeassistant/files/homeassistant-local.pp b/roles/homeassistant/files/homeassistant-local.pp
index e3fe854..e202a25 100644
Binary files a/roles/homeassistant/files/homeassistant-local.pp and b/roles/homeassistant/files/homeassistant-local.pp differ
diff --git a/roles/homeassistant/files/homeassistant-local.te b/roles/homeassistant/files/homeassistant-local.te
index 60f2983..e6b5e2b 100644
--- a/roles/homeassistant/files/homeassistant-local.te
+++ b/roles/homeassistant/files/homeassistant-local.te
@@ -1,11 +1,12 @@
-module homeassistant-local 1.0;
+module homeassistant-local 1.1;
require {
type container_t;
type system_dbusd_var_run_t;
type system_dbusd_t;
type bluetooth_t;
+ class dir read;
class sock_file write;
class unix_stream_socket connectto;
class dbus send_msg;
@@ -18,4 +19,5 @@ allow bluetooth_t container_t:dbus send_msg;
allow container_t bluetooth_t:dbus send_msg;
allow container_t system_dbusd_t:dbus send_msg;
allow container_t system_dbusd_t:unix_stream_socket connectto;
+allow container_t system_dbusd_var_run_t:dir read;
allow container_t system_dbusd_var_run_t:sock_file write;
diff --git a/roles/homeassistant/handlers/main.yml b/roles/homeassistant/handlers/main.yml
index 61fb83a..36f24f6 100644
--- a/roles/homeassistant/handlers/main.yml
+++ b/roles/homeassistant/handlers/main.yml
@@ -1,5 +1,6 @@
---
- name: Restart homeassistant
- ansible.builtin.service:
+ ansible.builtin.systemd_service:
name: homeassistant-container
state: restarted
+ daemon_reload: true
diff --git a/roles/homeassistant/meta/main.yml b/roles/homeassistant/meta/main.yml
index 305b1b2..34c289c 100644
--- a/roles/homeassistant/meta/main.yml
+++ b/roles/homeassistant/meta/main.yml
@@ -2,3 +2,4 @@
dependencies:
- {role: nginx}
- {role: podman}
+ - {role: udev}
diff --git a/roles/homeassistant/tasks/main.yml b/roles/homeassistant/tasks/main.yml
index f2f53d1..746b312 100644
--- a/roles/homeassistant/tasks/main.yml
+++ b/roles/homeassistant/tasks/main.yml
@@ -1,19 +1,71 @@
---
- name: Create group
ansible.builtin.group:
- name: ha
+ name: homeassistant
- name: Create user
ansible.builtin.user:
- name: ha
+ name: homeassistant
comment: Podman HomeAssistant
- group: ha
+ group: homeassistant
shell: /sbin/nologin
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - homeassistant
+ creates: /var/lib/systemd/linger/homeassistant
+
- name: Install dependencies
ansible.builtin.package:
- name: bluez
+ name: "{{ item }}"
state: installed
+ with_items:
+ - bluez
+ - git
+ - patch
+ - yamllint
+
+- name: Get venv support for container
+ ansible.builtin.git:
+ dest: /usr/local/src/homeassistant-docker-venv
+ repo: https://github.com/tribut/homeassistant-docker-venv.git
+ update: true
+ version: master
+ register: git_result
+
+- name: Create venv support directory
+ ansible.builtin.file:
+ path: /usr/local/libexec/homeassistant-docker-venv
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Check if venv support script exists
+ ansible.builtin.stat:
+ path: /usr/local/libexec/homeassistant-docker-venv/run
+ changed_when: false
+ register: stat_result
+
+- name: Copy venv support script
+ ansible.builtin.copy:
+ dest: /usr/local/libexec/homeassistant-docker-venv/run
+ src: /usr/local/src/homeassistant-docker-venv/run
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ remote_src: true
+ when: not stat_result.stat.exists or git_result.changed
+
+# https://github.com/home-assistant/core/issues/128214
+- name: Patch venv support script
+ ansible.posix.patch:
+ dest: /usr/local/libexec/homeassistant-docker-venv/run
+ src: homeassistant-docker-venv.patch
+ notify: Restart homeassistant
- name: Enable bluetooth services
ansible.builtin.service:
@@ -25,7 +77,7 @@
ansible.builtin.copy:
dest: /usr/local/share/selinux/homeassistant-local.pp
src: homeassistant-local.pp
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -52,13 +104,28 @@
setype: container_file_t
when: ansible_selinux_python_present
+- name: Allow podman to use devices
+ ansible.posix.seboolean:
+ name: container_use_devices
+ state: true
+ persistent: true
+
+- name: Allow homeassistant to connect specific devices
+ ansible.builtin.copy:
+ dest: /etc/udev/rules.d/99-homeassistant.rules
+ src: 99-homeassistant.rules
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Reload udev rules
+
- name: Create config directory
ansible.builtin.file:
path: /export/homeassistant
state: directory
- mode: 0700
- owner: ha
- group: ha
+ mode: "0700"
+ owner: homeassistant
+ group: homeassistant
setype: _default
- name: Link config directory
@@ -72,18 +139,49 @@
- name: Copy authentication command
ansible.builtin.copy:
- dest: /srv/homeassistant/auth-command.sh
- src: auth-command.sh
- mode: 0755
+ dest: /srv/homeassistant/auth-command.py
+ src: auth-command.py
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
setype: _default
+- name: Create directories for custom integrations
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ setype: _default
+ with_items:
+ - /srv/homeassistant/custom_components
+ - /srv/homeassistant/downloads
+
+- name: Download extra integrations
+ ansible.builtin.git:
+ dest: "/srv/homeassistant/downloads/{{ item.name }}"
+ repo: "{{ item.repo }}"
+ update: true
+ version: "{{ item.version }}"
+ notify: Restart homeassistant
+ with_items: "{{ homeassistant_integrations | default([]) }}"
+
+- name: Link extra integrations
+ ansible.builtin.file:
+ dest: "/srv/homeassistant/custom_components/{{ item.name }}"
+ src: "../downloads/{{ item.name }}/custom_components/{{ item.name }}"
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+ with_items: "{{ homeassistant_integrations | default([]) }}"
+
- name: Create service file
ansible.builtin.template:
dest: /etc/systemd/system/homeassistant-container.service
src: homeassistant-container.service.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart homeassistant
@@ -99,9 +197,9 @@
dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/homeassistant.conf"
content: |
location / {
- proxy_pass http://127.0.0.1:8001;
+ proxy_pass http://127.0.0.1:8008;
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
diff --git a/roles/homeassistant/templates/homeassistant-container.service.j2 b/roles/homeassistant/templates/homeassistant-container.service.j2
index 8c83714..a22c105 100644
--- a/roles/homeassistant/templates/homeassistant-container.service.j2
+++ b/roles/homeassistant/templates/homeassistant-container.service.j2
@@ -4,14 +4,19 @@ Wants=network-online.target
After=network-online.target
[Service]
-User=ha
+User=homeassistant
ExecStart=/usr/bin/podman run \
- --rm -p 127.0.0.1:8001:8123 \
+ --rm -p 127.0.0.1:8008:8123 \
--name homeassistant \
+ --env PGID=1000 \
+ --env PUID=1000 \
--env TZ=Europe/Helsinki \
+ --env UMASK=007 \
--userns keep-id \
+ --device /dev/ttyUSB0 \
--volume /run/dbus:/run/dbus:ro \
--volume /srv/homeassistant:/config:rw \
+ --volume /usr/local/libexec/homeassistant-docker-venv/run:/etc/services.d/home-assistant/run:ro \
docker.io/homeassistant/home-assistant:{{ homeassistant_version }}
ExecStop=/usr/bin/podman stop --ignore homeassistant
ExecStopPost=/usr/bin/podman rm -f --ignore homeassistant
diff --git a/roles/ifstated/tasks/main.yml b/roles/ifstated/tasks/main.yml
index 6dc9181..ec548b0 100644
--- a/roles/ifstated/tasks/main.yml
+++ b/roles/ifstated/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.template:
dest: /etc/ifstated.conf
src: "{{ ifstated_config }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
# validate: "ifstated -n -f %s"
diff --git a/roles/ifstated/templates/ifstated-dna.conf.j2 b/roles/ifstated/templates/ifstated-dna.conf.j2
index 7fcbd5f..ed794f3 100644
--- a/roles/ifstated/templates/ifstated-dna.conf.j2
+++ b/roles/ifstated/templates/ifstated-dna.conf.j2
@@ -17,10 +17,9 @@ state master {
init {
# spoof mac to keep dhcp lease in sync with both gw's
run "/sbin/ifconfig vio1 lladdr {{ gw_home_mac }} up"
- # flush routes and run dhclient and dhcpcd
+ # flush routes and renew lease
run "/sbin/route -qn flush"
- run "/sbin/dhclient vio1"
- #run "/sbin/rcctl restart dhcpcd > /dev/null"
+ run "/usr/sbin/dhcpleasectl vio1"
# reset firewall rules
run "sleep 5 ; pfctl -f /etc/pf.conf"
}
@@ -31,8 +30,6 @@ state master {
state backup {
init {
- # kill dhclient (TODO: better command for this)
- run "pkill -9 dhclient"
# bring down interface and reset mac
run "/sbin/ifconfig vio1 delete lladdr {{ gw_home_mac }} down"
# flush routes and fix default route
diff --git a/roles/influxdb/meta/main.yml b/roles/influxdb/meta/main.yml
index b95ceec..954fabd 100644
--- a/roles/influxdb/meta/main.yml
+++ b/roles/influxdb/meta/main.yml
@@ -1,3 +1,3 @@
---
dependencies:
- - {role: nginx/server}
+ - {role: nginx}
diff --git a/roles/influxdb/tasks/main.yml b/roles/influxdb/tasks/main.yml
index 90d8046..f77db0b 100644
--- a/roles/influxdb/tasks/main.yml
+++ b/roles/influxdb/tasks/main.yml
@@ -38,7 +38,7 @@
ansible.builtin.file:
path: /etc/logrotate.d/influxdb
state: file
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -46,7 +46,7 @@
ansible.builtin.file:
path: /export/influxdb
state: directory
- mode: 0750
+ mode: "0750"
owner: influxdb
group: influxdb
@@ -63,7 +63,7 @@
ansible.builtin.copy:
dest: /etc/influxdb/config.toml
src: config.toml
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart influxdb
@@ -87,7 +87,7 @@
location / {
proxy_pass http://127.0.0.1:8086/;
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
diff --git a/roles/ipsilon/README.md b/roles/ipsilon/README.md
new file mode 100644
index 0000000..5e29d18
--- /dev/null
+++ b/roles/ipsilon/README.md
@@ -0,0 +1,28 @@
+== Creating openidc key ==
+
+Create two rsa keys:
+```
+openssl genrsa -out signing.key 4096
+openssl genrsa -out encryption.key 4096
+```
+
+Create JWK keys:
+```
+python3 -c '
+from datetime import datetime
+from jwcrypto.jwk import JWK, JWKSet
+keyset = JWKSet()
+date = datetime.now().strftime("%Y%m%d")
+with open("./signing.key", "r") as key:
+ jwkkey = JWK.from_pem(key.read().encode("UTF-8"))
+ jwkkey.update(use="sig")
+ jwkkey.update(kid=f"{date}-sig")
+ keyset.add(jwkkey)
+with open("./encryption.key", "r") as key:
+ jwkkey = JWK.from_pem(key.read().encode("UTF-8"))
+ jwkkey.update(use="enc")
+ jwkkey.update(kid=f"{date}-enc")
+ keyset.add(jwkkey)
+print(keyset.export())
+'
+```
diff --git a/roles/ipsilon/handlers/main.yml b/roles/ipsilon/handlers/main.yml
new file mode 100644
index 0000000..072010a
--- /dev/null
+++ b/roles/ipsilon/handlers/main.yml
@@ -0,0 +1,18 @@
+---
+- name: Rebuild ipsilon-container
+ ansible.builtin.command:
+ argv:
+ - podman
+ - build
+ - -t
+ - ipsilon
+ - /usr/local/src/docker-ipsilon
+ become: true
+ become_user: ipsilon
+ notify: Restart ipsilon-container
+
+- name: Restart ipsilon-container
+ ansible.builtin.systemd:
+ name: ipsilon-container
+ daemon_reload: true
+ state: restarted
diff --git a/roles/ipsilon/meta/main.yml b/roles/ipsilon/meta/main.yml
new file mode 100644
index 0000000..b8e2a3e
--- /dev/null
+++ b/roles/ipsilon/meta/main.yml
@@ -0,0 +1,5 @@
+---
+dependencies:
+ - {role: git}
+ - {role: nginx}
+ - {role: podman}
diff --git a/roles/ipsilon/tasks/main.yml b/roles/ipsilon/tasks/main.yml
new file mode 100644
index 0000000..c82bcd1
--- /dev/null
+++ b/roles/ipsilon/tasks/main.yml
@@ -0,0 +1,128 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: ipsilon
+
+- name: Create user
+ ansible.builtin.user:
+ name: ipsilon
+ comment: Podman Ipsilon
+ group: ipsilon
+ shell: /sbin/nologin
+
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - ipsilon
+ creates: /var/lib/systemd/linger/ipsilon
+
+- name: Copy host key
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/ipsilon.key"
+ src: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ mode: "0640"
+ owner: root
+ group: ipsilon
+ remote_src: true
+
+- name: Copy OIDC key
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/openidc.key"
+ src: "{{ ansible_private }}/files/ipsilon/openidc.key"
+ mode: "0640"
+ owner: root
+ group: ipsilon
+ notify: Restart ipsilon-container
+
+- name: Fix SELinux contexts from config directory
+ community.general.sefcontext:
+ path: /etc/ipsilon(/.*)?
+ setype: container_file_t
+ when: ansible_selinux_python_present
+
+- name: Get subuid number
+ ansible.builtin.command:
+ argv:
+ - awk
+ - "-F:"
+ - '{ if ($1 == "ipsilon") print $2 + 899 }'
+ - /etc/subuid
+ changed_when: false
+ register: subuid
+
+- name: Get subgid number
+ ansible.builtin.command:
+ argv:
+ - awk
+ - "-F:"
+ - '{ if ($1 == "ipsilon") print $2 + 899 }'
+ - /etc/subgid
+ changed_when: false
+ register: subgid
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/ipsilon
+ state: directory
+ mode: "0750"
+ owner: root
+ group: ipsilon
+ setype: _default
+
+- name: Create OIDC static config
+ ansible.builtin.template:
+ dest: /etc/ipsilon/openidc-static.conf
+ src: openidc-static.conf.j2
+ mode: "0600"
+ owner: "{{ subuid.stdout }}"
+ group: "{{ subgid.stdout }}"
+ setype: _default
+ notify: Restart ipsilon-container
+
+- name: Get container source
+ ansible.builtin.git:
+ dest: /usr/local/src/docker-ipsilon
+ repo: https://github.com/foo-sh/docker-ipsilon.git
+ update: true
+ version: master
+ notify: Rebuild ipsilon-container
+
+- name: Create service file
+ ansible.builtin.template:
+ dest: /etc/systemd/system/ipsilon-container.service
+ src: ipsilon-container.service.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart ipsilon-container
+
+- name: Create service config
+ ansible.builtin.template:
+ dest: /etc/sysconfig/ipsilon-container
+ src: ipsilon-container.sysconfig.j2
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart ipsilon-container
+
+- name: Enable service
+ ansible.builtin.service:
+ name: ipsilon-container
+ state: started
+ enabled: true
+
+- name: Copy nginx config
+ ansible.builtin.copy:
+ dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/ipsilon-container.conf"
+ content: |
+ location /ipsilon {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Host idp.foo.sh;
+ proxy_pass http://127.0.0.1:8011/;
+ }
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
diff --git a/roles/ipsilon/templates/ipsilon-container.service.j2 b/roles/ipsilon/templates/ipsilon-container.service.j2
new file mode 100644
index 0000000..2c08f94
--- /dev/null
+++ b/roles/ipsilon/templates/ipsilon-container.service.j2
@@ -0,0 +1,23 @@
+[Unit]
+Description=Ipsilon Container
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+User=ipsilon
+EnvironmentFile=/etc/sysconfig/ipsilon-container
+ExecStart=/usr/bin/podman run \
+ --rm -p 127.0.0.1:8011:80 \
+ --name ipsilon \
+ --env LDAP_* --env IPSILON_*\
+ --volume={{ tls_certs }}/ca.crt:/etc/pki/tls/certs/ca.crt:ro \
+ --volume={{ tls_certs }}/{{ inventory_hostname }}.crt:/etc/pki/tls/certs/{{ inventory_hostname }}.crt:ro \
+ --volume={{ tls_private }}/ipsilon.key:/etc/pki/tls/private/{{ inventory_hostname }}.key:ro \
+ --volume={{ tls_private }}/openidc.key:/etc/ipsilon/openidc.key:ro \
+ --volume=/etc/ipsilon/openidc-static.conf:/etc/ipsilon/root/openidc-static.conf:rw \
+ ipsilon:latest
+ExecStop=/usr/bin/podman stop --ignore ipsilon
+ExecStopPost=/usr/bin/podman rm -f --ignore ipsilon
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/ipsilon/templates/ipsilon-container.sysconfig.j2 b/roles/ipsilon/templates/ipsilon-container.sysconfig.j2
new file mode 100644
index 0000000..4150eaf
--- /dev/null
+++ b/roles/ipsilon/templates/ipsilon-container.sysconfig.j2
@@ -0,0 +1,11 @@
+LDAP_BASEDN="{{ ldap_basedn }}"
+LDAP_BINDPW="{{ ipsilon_ldap_pass }}"
+IPSILON_DB_USER="ipsilon"
+IPSILON_DB_PASS="{{ ipsilon_mysql_pass }}"
+IPSILON_DB_HOST="sqldb02.home.foo.sh"
+IPSILON_DB_CA="{{ tls_certs }}/ca.crt"
+IPSILON_DB_KEY="{{ tls_private }}/{{ inventory_hostname }}.key"
+IPSILON_DB_CERT="{{ tls_certs }}/{{ inventory_hostname}}.crt"
+IPSILON_HOSTNAME="idp.foo.sh"
+IPSILON_OPENIDC_KEYID="{{ ipsilon_openidc_keyid }}"
+IPSILON_OPENIDC_SALT="{{ ipsilon_openidc_salt }}"
diff --git a/roles/ipsilon/templates/openidc-static.conf.j2 b/roles/ipsilon/templates/openidc-static.conf.j2
new file mode 100644
index 0000000..f6bb88d
--- /dev/null
+++ b/roles/ipsilon/templates/openidc-static.conf.j2
@@ -0,0 +1,26 @@
+[client]
+{% for client in openidc_clients %}
+{{ client["name"] }} application_type="web"
+{{ client["name"] }} client_id=null
+{{ client["name"] }} client_id_issued_at=0
+{{ client["name"] }} client_name="{{ client["name"] }}"
+{{ client["name"] }} client_secret="{{ client["client_secret"] }}"
+{{ client["name"] }} client_secret_expires_at=0
+{{ client["name"] }} client_uri="{{ client["client_uri"] }}"
+{{ client["name"] }} contacts=["adm@foo.sh"]
+{{ client["name"] }} grant_types=["authorization_code"]
+{{ client["name"] }} id_token_signed_response_alg="RS256"
+{{ client["name"] }} ipsilon_internal={"type": "static", "client_id": "{{ client["name"] }}", "trusted": true}
+{{ client["name"] }} jwks=null
+{{ client["name"] }} jwks_uri=null
+{{ client["name"] }} logo_uri=null
+{{ client["name"] }} policy_uri=null
+{{ client["name"] }} redirect_uris={{ client["redirect_uris"] | ansible.builtin.to_json }}
+{{ client["name"] }} request_uris=[]
+{{ client["name"] }} require_auth_time=null
+{{ client["name"] }} response_types=["code"]
+{{ client["name"] }} subject_type="pairwise"
+{{ client["name"] }} sector_identifier_uri=null
+{{ client["name"] }} token_endpoint_auth_method="{{ client["token_endpoint_auth_method"] | default("client_secret_post") }}"
+{{ client["name"] }} tos_uri=null
+{% endfor %}
diff --git a/roles/iptables/tasks/main.yml b/roles/iptables/tasks/main.yml
index aa52ce5..f01888c 100644
--- a/roles/iptables/tasks/main.yml
+++ b/roles/iptables/tasks/main.yml
@@ -16,7 +16,7 @@
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "/etc/sysconfig/{{ item }}"
- mode: 0600
+ mode: "0600"
owner: root
group: root
notify: "Reload {{ item }}"
diff --git a/roles/kadmin/tasks/main.yml b/roles/kadmin/tasks/main.yml
index 3b8ccc1..447b344 100644
--- a/roles/kadmin/tasks/main.yml
+++ b/roles/kadmin/tasks/main.yml
@@ -11,7 +11,7 @@
ansible.builtin.template:
dest: /var/kerberos/krb5kdc/kdc.conf
src: kdc.conf.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/kdc/tasks/main.yml b/roles/kdc/tasks/main.yml
index a2dcd3b..f7ef8eb 100644
--- a/roles/kdc/tasks/main.yml
+++ b/roles/kdc/tasks/main.yml
@@ -10,11 +10,19 @@
group: kdc
shell: /sbin/nologin
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - kdc
+ creates: /var/lib/systemd/linger/kdc
+
- name: Get container source
ansible.builtin.git:
dest: /usr/local/src/docker-kdc
repo: https://github.com/foo-sh/docker-kdc.git
- update: false
+ update: true
version: main
notify: Rebuild kdc-container
@@ -22,7 +30,7 @@
ansible.builtin.template:
dest: /etc/sysconfig/kdc-container
src: kdc-container.sysconfig.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
@@ -30,7 +38,7 @@
ansible.builtin.copy:
dest: /etc/systemd/system/kdc-container.service
src: kdc-container.service
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -47,7 +55,7 @@
location /KdcProxy {
proxy_pass http://127.0.0.1:8001;
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
diff --git a/roles/keytab/defaults/main.yml b/roles/keytab/defaults/main.yml
index 8b08f0a..e4c4ebf 100644
--- a/roles/keytab/defaults/main.yml
+++ b/roles/keytab/defaults/main.yml
@@ -1,3 +1,3 @@
---
-keytab: /etc/krb5.keytab
-group: "{{ ansible_wheel }}"
+keytab_path: /etc/krb5.keytab
+keytab_group: "{{ ansible_wheel }}"
diff --git a/roles/keytab/files/empty.keytab b/roles/keytab/files/empty.keytab
new file mode 100644
index 0000000..2e2a96a
--- /dev/null
+++ b/roles/keytab/files/empty.keytab
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/roles/keytab/tasks/main.yml b/roles/keytab/tasks/main.yml
index c4e5496..ef83269 100644
--- a/roles/keytab/tasks/main.yml
+++ b/roles/keytab/tasks/main.yml
@@ -1,50 +1,61 @@
---
- name: Check if keytab exists
ansible.builtin.stat:
- path: "{{ keytab }}"
+ path: "{{ keytab_path }}"
register: keytab_status
check_mode: false
-- name: Add principal to keytab
- ansible.builtin.command:
- argv:
- - kadmin.local
- - -x
- - host=ldaps://ldap01.foo.sh
- - ktadd
- - -k
- - "/tmp/{{ inventory_hostname }}.kt"
- - "{{ item }}"
- with_items: "{{ principals }}"
- delegate_to: ldap01.home.foo.sh
- when: not keytab_status.stat.exists
+- name: Create keytab
+ block:
+ - name: Create temporary file
+ ansible.builtin.tempfile:
+ state: file
+ register: tempfile
-- name: Get keytab
- ansible.builtin.command:
- argv:
- - base64
- - "/tmp/{{ inventory_hostname }}.kt"
- register: keytab_data
- delegate_to: ldap01.home.foo.sh
- when: not keytab_status.stat.exists
+ - name: Initialize keytab
+ ansible.builtin.copy:
+ dest: "{{ tempfile.path }}"
+ src: empty.keytab
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
-- name: Delete temporary file
- ansible.builtin.file:
- path: "/tmp/{{ inventory_hostname }}.kt"
- state: absent
- delegate_to: ldap01.home.foo.sh
+ - name: Add principal to keytab
+ ansible.builtin.command:
+ argv:
+ - kadmin.local
+ - -x
+ - host=ldaps://ldap01.foo.sh
+ - ktadd
+ - -k
+ - "{{ tempfile.path }}"
+ - "{{ item }}"
+ with_items: "{{ keytab_principals }}"
+
+ - name: Get keytab
+ ansible.builtin.command:
+ argv:
+ - base64
+ - "{{ tempfile.path }}"
+ register: keytab_data
+
+ - name: Delete temporary file
+ ansible.builtin.file:
+ path: "{{ tempfile.path }}"
+ state: absent
when: not keytab_status.stat.exists
+ delegate_to: ldap01.home.foo.sh
- name: Deploy keytab file
ansible.builtin.shell: >-
set -o pipefail &&
umask 077 &&
- echo '{{ keytab_data.stdout }}' | base64 -d > "{{ keytab }}"
+ echo '{{ keytab_data.stdout }}' | base64 -d > "{{ keytab_path }}"
when: not keytab_status.stat.exists
- name: Check keytab permissions
ansible.builtin.file:
- path: "{{ keytab }}"
- mode: "{% if group == ansible_wheel %}0600{% else %}0640{% endif %}"
+ path: "{{ keytab_path }}"
+ mode: "{% if keytab_group == ansible_wheel %}0600{% else %}0640{% endif %}"
owner: root
- group: "{{ group }}"
+ group: "{{ keytab_group }}"
diff --git a/roles/kvm_host/files/check-orphaned-vm.sh b/roles/kvm_host/files/check-orphaned-vm.sh
new file mode 100755
index 0000000..43954e1
--- /dev/null
+++ b/roles/kvm_host/files/check-orphaned-vm.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+set -eu
+
+# check that all vm's are in ldap
+virsh list --all --name | while read -r vm ; do
+ [ "$vm" = "" ] && continue
+ if ! ldapsearch -LLL "(&(cn=${vm})(objectClass=device))" dn 2> /dev/null | \
+ grep -qE "^dn: cn=${vm},ou=Hosts,"
+ then
+ echo "WARNING: Host \"${vm}\" registered in KVM but not in LDAP" 1>62
+ fi
+done
+
+# check that all disks have owner
+for dir in /srv/libvirt/{hdd,nvme,os,ssd} ; do
+ [ -d "$dir" ] || continue
+ find "$dir" -name \*.img | while read -r image ; do
+ vm="$(basename "$image" ".img" | sed -e 's/\.[a-z]$//')"
+ if ! virsh dominfo "$vm" > /dev/null 2>&1 ; then
+ echo "WARNING: Orphaned disk image \"${image}\" found" 1>&2
+ fi
+ done
+done
diff --git a/roles/kvm_host/meta/main.yml b/roles/kvm_host/meta/main.yml
new file mode 100644
index 0000000..d2f9d51
--- /dev/null
+++ b/roles/kvm_host/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: ldap}
diff --git a/roles/kvm_host/tasks/main.yml b/roles/kvm_host/tasks/main.yml
index bafddde..78ea78e 100644
--- a/roles/kvm_host/tasks/main.yml
+++ b/roles/kvm_host/tasks/main.yml
@@ -7,7 +7,7 @@
blacklist bluetooth
blacklist btintel
blacklist btusb
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -29,13 +29,15 @@
ansible.builtin.file:
path: "{{ item }}"
state: directory
- mode: 0770
+ mode: "0770"
owner: root
group: qemu
with_items:
- /export/libvirt
- /export/libvirt/hdd
+ - /export/libvirt/nvme
- /export/libvirt/ssd
+ - /export/libvirt/os
- name: Link data directory
ansible.builtin.file:
@@ -51,3 +53,18 @@
name: libvirtd
state: started
enabled: true
+
+- name: Install script for checking orphaned vm's
+ ansible.builtin.copy:
+ dest: /usr/local/bin/check-orphaned-vm
+ src: check-orphaned-vm.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Add cronjob to check orphaned vm's
+ ansible.builtin.cron:
+ name: check-orphaned-vm
+ hour: "5"
+ minute: "5"
+ job: /usr/local/bin/check-orphaned-vm
diff --git a/roles/ldap_gravatar/tasks/main.yml b/roles/ldap_gravatar/tasks/main.yml
index ea21621..ee61b2d 100644
--- a/roles/ldap_gravatar/tasks/main.yml
+++ b/roles/ldap_gravatar/tasks/main.yml
@@ -11,7 +11,7 @@
ansible.builtin.copy:
src: gravatar-update.py
dest: /usr/local/sbin/gravatar-update
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/ldap_netdb/tasks/main.yml b/roles/ldap_netdb/tasks/main.yml
index 53b6d45..11b0275 100644
--- a/roles/ldap_netdb/tasks/main.yml
+++ b/roles/ldap_netdb/tasks/main.yml
@@ -12,7 +12,7 @@
ansible.builtin.copy:
src: netdb-update.py
dest: /usr/local/sbin/netdb-update
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/ldap_server/defaults/main.yml b/roles/ldap_server/defaults/main.yml
index 3454578..0563395 100644
--- a/roles/ldap_server/defaults/main.yml
+++ b/roles/ldap_server/defaults/main.yml
@@ -5,3 +5,4 @@ ldap_datadir: >-
{% if ansible_local['export'] %}/export{% else %}/srv{% endif %}/ldap
ldap_backupdir: >-
{% if ansible_local['export'] -%}/export{% else -%}/srv{% endif -%}/backup
+ldap_master: false
diff --git a/roles/ldap_server/files/ldap-backup.sh b/roles/ldap_server/files/ldap-backup.sh
index 7942743..2e84891 100755
--- a/roles/ldap_server/files/ldap-backup.sh
+++ b/roles/ldap_server/files/ldap-backup.sh
@@ -12,23 +12,24 @@ if [ "$(whoami)" != "root" ]; then
fi
BACKUPDIR="/srv/backup"
-BACKUPAGE="7"
+BACKUPAGE="30"
DATE="$(date '+%Y-%m-%d')"
+cd "$BACKUPDIR"
+
ldapsearch -LLL -x -H ldapi:// -s base -b 'cn=Databases,cn=Monitor' \
'(objectClass=*)' namingContexts | \
sed -n 's/^namingContexts: \(.*\)/\1/p' | while read -r db ; do
- [ "${db}" = "cn=config" ] && continue
- if ! slapcat -f /etc/openldap/slapd.conf -b "${db}" 2> /dev/null | \
- gzip > "${BACKUPDIR}/${db}.${DATE}.gz" ; then
+ [ "$db" = "cn=config" ] && continue
+ if ! slapcat -f /etc/openldap/slapd.conf -b "$db" 2> /dev/null | \
+ gzip > "${db}.${DATE}.gz"
+ then
echo "ERR: Failed to backup database ${db}" 1>&2
continue
fi
chgrp backup "${BACKUPDIR}/${db}.${DATE}.gz"
done
-cd ${BACKUPDIR} && {
- find . -xdev -depth -mindepth 1 -maxdepth 1 -type f -mtime +${BACKUPAGE} \
- -name '*.gz' -execdir rm -f -- {} \;
-}
+find . -xdev -depth -mindepth 1 -maxdepth 1 -type f -mtime +${BACKUPAGE} \
+ -name '*.gz' -execdir rm -f -- {} \;
diff --git a/roles/ldap_server/meta/main.yml b/roles/ldap_server/meta/main.yml
index e59e67d..84aca43 100644
--- a/roles/ldap_server/meta/main.yml
+++ b/roles/ldap_server/meta/main.yml
@@ -1,5 +1,6 @@
---
dependencies:
+ - {role: backup_base}
- {role: kerberos}
- {role: ldap}
- {role: saslauthd}
diff --git a/roles/ldap_server/tasks/main.yml b/roles/ldap_server/tasks/main.yml
index c7e54a4..834ac03 100644
--- a/roles/ldap_server/tasks/main.yml
+++ b/roles/ldap_server/tasks/main.yml
@@ -39,7 +39,7 @@
ansible.builtin.file:
path: "{{ ldap_datadir }}"
state: directory
- mode: 0700
+ mode: "0700"
owner: ldap
group: ldap
seuser: _default
@@ -48,44 +48,18 @@
- name: Link LDAP data directory
ansible.builtin.file:
path: /srv/ldap
- src: /export/ldap
+ src: "{{ ldap_datadir }}"
state: link
owner: root
group: root
follow: false
when: ldap_datadir != "/srv/ldap"
-- name: Import sftpuser role
- ansible.builtin.import_role:
- name: sftpuser
- vars:
- chroot: /srv/backup
- user: backup
- publickeys: "{{ backup_publickeys }}"
-
-- name: Create backup directory
- ansible.builtin.file:
- path: "{{ ldap_backupdir }}"
- state: directory
- mode: 0750
- owner: root
- group: backup
-
-- name: Link backup directory
- ansible.builtin.file:
- path: /srv/backup
- src: /export/backup
- state: link
- owner: root
- group: "{{ ansible_wheel }}"
- follow: false
- when: ldap_backupdir != "/srv/backup"
-
- name: Copy backup script
ansible.builtin.copy:
dest: /usr/local/sbin/ldap-backup
src: ldap-backup.sh
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -101,7 +75,7 @@
ansible.builtin.copy:
dest: /usr/local/sbin/ldapspn
src: ldapspn.py
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
when: ldap_master is defined
@@ -121,7 +95,7 @@
dest: /etc/sasl2/slapd.conf
content: |
pwcheck_method: saslauthd
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart slapd
@@ -130,7 +104,7 @@
ansible.builtin.copy:
dest: "{{ tls_certs }}/{{ ldap_server_cert }}.crt"
src: "/srv/letsencrypt/live/{{ ldap_server_cert }}/cert.pem"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
tags: certificates
@@ -140,7 +114,7 @@
ansible.builtin.copy:
dest: "{{ tls_private }}/{{ ldap_server_cert }}.key"
src: "/srv/letsencrypt/live/{{ ldap_server_cert }}/privkey.pem"
- mode: 0640
+ mode: "0640"
owner: root
group: ldap
tags: certificates
@@ -150,7 +124,7 @@
ansible.builtin.copy:
dest: "{{ tls_certs }}/{{ ldap_server_cert }}-chain.crt"
src: "/srv/letsencrypt/live/{{ ldap_server_cert }}/chain.pem"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
tags: certificates
@@ -168,6 +142,7 @@
delegate_to: localhost
register: result
changed_when: false
+ check_mode: false
tags: certificates
- name: Link server chain certificate
@@ -193,7 +168,7 @@
ansible.builtin.file:
path: /etc/systemd/system/slapd.service.d
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
when: ansible_distribution == "Rocky"
@@ -202,7 +177,7 @@
ansible.builtin.copy:
dest: /etc/systemd/system/slapd.service.d/local.conf
src: slapd.service
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart slapd
@@ -212,7 +187,7 @@
ansible.builtin.copy:
dest: /etc/sysconfig/slapd
src: slapd.sysconfig
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart slapd
@@ -222,7 +197,7 @@
ansible.builtin.copy:
dest: "/etc/openldap/schema/{{ item }}"
src: "{{ item }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
with_items:
@@ -237,7 +212,7 @@
ansible.builtin.copy:
dest: /etc/openldap/check_password.conf
src: check_password.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -245,7 +220,7 @@
ansible.builtin.template:
dest: /etc/openldap/slapd.conf
src: slapd.conf.j2
- mode: 0640
+ mode: "0640"
owner: root
group: ldap
notify: Restart slapd
@@ -272,6 +247,6 @@
ansible.builtin.copy:
dest: /etc/openldap/slapd.keytab
src: "{{ ansible_private }}/files/keytabs/slapd.keytab"
- mode: 0640
+ mode: "0640"
owner: root
group: ldap
diff --git a/roles/ldap_server/templates/slapd.conf.j2 b/roles/ldap_server/templates/slapd.conf.j2
index 903639c..98efbea 100644
--- a/roles/ldap_server/templates/slapd.conf.j2
+++ b/roles/ldap_server/templates/slapd.conf.j2
@@ -88,7 +88,7 @@ memberof-memberof-ad memberOf
# access without access to clear text data
directory /srv/ldap
-{% if ldap_master is not defined %}
+{% if not ldap_master %}
# replication
syncrepl rid={{ 999 | random(seed=inventory_hostname) }}
provider=ldaps://ldap01.foo.sh
@@ -139,6 +139,10 @@ authz-regexp
"uid=([^.]\+),cn=login,cn=auth"
"ldap:///{{ ldap_basedn }}??sub?(&(uid=$1)(objectClass=posixAccount))"
+# allow everyone to read root object
+access to dn.base={{ ldap_basedn }}
+ by * read
+
# require authentication for authenticated users that don't match above
access to *
by dn.children="cn=peercred,cn=external,cn=auth" auth
diff --git a/roles/lm_sensors/handlers/main.yml b/roles/lm_sensors/handlers/main.yml
deleted file mode 100644
index ea6cb47..0000000
--- a/roles/lm_sensors/handlers/main.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-- name: Run sensors-detect
- ansible.builtin.shell: "cat /dev/null | sensors-detect"
-
-- name: Restart lm_sensors
- ansible.builtin.service:
- name: lm_sensors
- state: restarted
diff --git a/roles/lm_sensors/tasks/main.yml b/roles/lm_sensors/tasks/main.yml
deleted file mode 100644
index 9231b53..0000000
--- a/roles/lm_sensors/tasks/main.yml
+++ /dev/null
@@ -1,12 +0,0 @@
----
-- name: Install packages
- ansible.builtin.package:
- name: lm_sensors
- state: installed
- notify: Run sensors-detect
-
-- name: Enable service
- ansible.builtin.service:
- name: lm_sensors
- state: started
- enabled: true
diff --git a/roles/mariadb/files/local.cnf b/roles/mariadb/files/local.cnf
new file mode 100644
index 0000000..cedabc6
--- /dev/null
+++ b/roles/mariadb/files/local.cnf
@@ -0,0 +1,4 @@
+[mariadb]
+innodb_file_per_table = ON
+general_log
+general_log_file = /var/log/mariadb/mariadb-query.log
diff --git a/roles/mariadb/files/mariadb-backup.sh b/roles/mariadb/files/mariadb-backup.sh
index e2181bb..9a4a354 100755
--- a/roles/mariadb/files/mariadb-backup.sh
+++ b/roles/mariadb/files/mariadb-backup.sh
@@ -4,23 +4,17 @@ set -eu
umask 027
-DESTDIR="/export/backup"
+DESTDIR="/srv/backup"
DATE="$(date +%Y-%m-%d)"
-if [ ! -d "$DESTDIR" ]; then
- echo "ERR: MariaDB backup directory [${DESTDIR}] does not exist" 1>&2
- exit 1
-fi
+cd "$DESTDIR"
+find . -xdev -mindepth 2 -maxdepth 2 -type f -mtime +30 \
+ -execdir rm -f -- {} \;
+find . -xdev -depth -mindepth 1 -maxdepth 1 -type d -empty \
+ -execdir rmdir -- {} \;
-cd "$DESTDIR" && {
- find . -xdev -mindepth 2 -maxdepth 2 -type f -mtime +7 \
- -execdir rm -f -- {} \;
- find . -xdev -depth -mindepth 1 -maxdepth 1 -type d -empty \
- -execdir rmdir -- {} \;
-}
-
-DESTDIR="${DESTDIR}/${DATE}"
-mkdir "$DESTDIR"
+mkdir -m 2770 "$DATE"
+chgrp backup "$DATE"
for db in $(mysql -e "show databases" -s) ; do
case "$db" in
@@ -28,5 +22,5 @@ for db in $(mysql -e "show databases" -s) ; do
continue
;;
esac
- mysqldump -E --add-drop-table "$db" | gzip > "${DESTDIR}/${db}.${DATE}.gz"
+ mysqldump -E --add-drop-table "$db" | gzip > "${DATE}/${db}.${DATE}.gz"
done
diff --git a/roles/mariadb/files/mariadb-querylog.logrotate b/roles/mariadb/files/mariadb-querylog.logrotate
new file mode 100644
index 0000000..70002a1
--- /dev/null
+++ b/roles/mariadb/files/mariadb-querylog.logrotate
@@ -0,0 +1,17 @@
+/var/log/mariadb/mariadb-query.log {
+ create 600 mysql mysql
+ su mysql mysql
+ notifempty
+ daily
+ rotate 3
+ missingok
+ compress
+ sharedscripts
+ postrotate
+ # just if mariadbd is really running
+ if [ -e /run/mariadb/mariadb.pid ]
+ then
+ kill -1 $(&2
+ exit 1
+fi
diff --git a/roles/mariadb/meta/main.yml b/roles/mariadb/meta/main.yml
new file mode 100644
index 0000000..f178512
--- /dev/null
+++ b/roles/mariadb/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: backup_base}
diff --git a/roles/mariadb/tasks/main.yml b/roles/mariadb/tasks/main.yml
index 519068d..b2a9ca9 100644
--- a/roles/mariadb/tasks/main.yml
+++ b/roles/mariadb/tasks/main.yml
@@ -16,7 +16,7 @@
ansible.builtin.file:
path: /export/mariadb
state: directory
- mode: 0750
+ mode: "0750"
owner: mysql
group: mysql
setype: _default
@@ -41,7 +41,7 @@
ansible.builtin.file:
path: /etc/mysql
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: mysql
@@ -56,7 +56,7 @@
ansible.builtin.template:
dest: /etc/my.cnf.d/tls.cnf
src: tls.cnf.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart mariadb
@@ -64,8 +64,8 @@
- name: Create local configuration
ansible.builtin.copy:
dest: /etc/my.cnf.d/local.cnf
- content: "[mariadb]\ninnodb_file_per_table=ON\n"
- mode: 0644
+ src: local.cnf
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart mariadb
@@ -91,41 +91,16 @@
ansible.builtin.template:
dest: /root/.my.cnf
src: my.cnf.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
when: mariadb_root_password is defined
-- name: Import sftpuser role
- ansible.builtin.import_role:
- name: sftpuser
- vars:
- chroot: /srv/backup
- user: backup
- publickeys: "{{ backup_publickeys }}"
-
-- name: Create backup directory
- ansible.builtin.file:
- path: /export/backup
- state: directory
- mode: 02750
- owner: root
- group: backup
-
-- name: Link backup directory
- ansible.builtin.file:
- path: /srv/backup
- src: /export/backup
- state: link
- owner: root
- group: "{{ ansible_wheel }}"
- follow: false
-
- name: Copy backup script
ansible.builtin.copy:
dest: /usr/local/sbin/mariadb-backup
src: mariadb-backup.sh
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -135,3 +110,26 @@
job: /usr/local/sbin/mariadb-backup
hour: "0"
minute: "30"
+
+- name: Add logrotate job for query log
+ ansible.builtin.copy:
+ dest: /etc/logrotate.d/mariadb-querylog
+ src: mariadb-querylog.logrotate
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Copy script to check timezone data
+ ansible.builtin.copy:
+ dest: /usr/local/sbin/mysql_tzinfo_check
+ src: mysql_tzinfo_check.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create cron job for checking timezone data
+ ansible.builtin.cron:
+ name: mysql_tzinfo_check
+ job: /usr/local/sbin/mysql_tzinfo_check
+ hour: "3"
+ minute: "15"
diff --git a/roles/mariadb/templates/tls.cnf.j2 b/roles/mariadb/templates/tls.cnf.j2
index e193b3f..7aebd43 100644
--- a/roles/mariadb/templates/tls.cnf.j2
+++ b/roles/mariadb/templates/tls.cnf.j2
@@ -2,3 +2,4 @@
ssl-cert = {{ tls_certs }}/{{ inventory_hostname }}.crt
ssl-key = {{ tls_private }}/{{ inventory_hostname }}.key
ssl-ca = {{ tls_certs }}/ca.crt
+tls_version = TLSv1.3
diff --git a/roles/minecraft/tasks/main.yml b/roles/minecraft/tasks/main.yml
index 91f0630..50961a4 100644
--- a/roles/minecraft/tasks/main.yml
+++ b/roles/minecraft/tasks/main.yml
@@ -7,13 +7,13 @@
- name: Create group
ansible.builtin.group:
name: minecraft
- gid: 1007
+ gid: 307
- name: Create user
ansible.builtin.user:
name: minecraft
comment: Service Minecraft
- uid: 1007
+ uid: 307
group: minecraft
create_home: false
home: /var/empty
@@ -23,7 +23,7 @@
ansible.builtin.file:
path: /export/minecraft
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: minecraft
@@ -40,7 +40,7 @@
ansible.builtin.file:
path: "/srv/minecraft/{{ item }}"
state: directory
- mode: 0770
+ mode: "0770"
owner: root
group: minecraft
with_items:
@@ -55,7 +55,7 @@
dest: /srv/minecraft/eula.txt
content: |
eula=true
- mode: 0640
+ mode: "0640"
owner: root
group: minecraft
@@ -63,7 +63,7 @@
ansible.builtin.copy:
dest: /srv/minecraft/server.properties
src: server.properties
- mode: 0640
+ mode: "0640"
owner: root
group: minecraft
@@ -72,7 +72,7 @@
dest: "/srv/minecraft/{{ item }}"
content: "[]"
force: false
- mode: 0660
+ mode: "0660"
owner: root
group: minecraft
with_items:
@@ -85,7 +85,7 @@
ansible.builtin.file:
path: /usr/local/lib/minecraft
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -95,7 +95,7 @@
url: >-
https://launcher.mojang.com/v1/objects/{{ minecraft_sha1sum }}/server.jar
checksum: "sha1:{{ minecraft_sha1sum }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -103,7 +103,7 @@
ansible.builtin.copy:
dest: /etc/systemd/system/minecraft.service
src: minecraft.service
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/mirror/base/files/sync-mirrors b/roles/mirror/base/files/sync-mirrors
deleted file mode 100755
index ef6100e..0000000
--- a/roles/mirror/base/files/sync-mirrors
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/bash
-
-LOCKFILE="/var/run/sync-mirrors/lockfile"
-LOGFILE="/var/log/sync-mirrors/sync-mirrors-$(date +%Y%m%d%H%M%S).log"
-CONFDIR="/etc/sync-mirrors"
-
-usage() {
- echo "Usage: $(basename "$0") [-v] [mirror]" 1>&2
- echo " $(basename "$0") -l" 1>&2
-}
-
-logmsg() {
- [ "${VERBOSE}" -eq 1 ] && echo "$1"
- echo "$(date '+%Y/%m/%d %H:%M:%S') [$$] $1" >> "${LOGFILE}"
-}
-
-if [ -d ${CONFDIR} ]; then
- MIRRORLIST="$(find ${CONFDIR}/ -name \*.conf | while read -r f ; \
- do basename "${f}" | sed -e 's/\.conf$//' ; done)"
- if [ "${MIRRORLIST}" = "" ]; then
- echo "ERR: No configured mirrors found" 1>&2
- exit 1
- fi
-else
- echo "ERR: Config directory [${CONFDIR}] missing" 1>&2
- exit 1
-fi
-
-VERBOSE=0
-NOOP=""
-EXTRA_OPTS=""
-while getopts "vhln" c ; do
- case $c in
- v)
- VERBOSE=1
- EXTRA_OPTS="${EXTRA_OPTS} -v --progress"
- ;;
- h)
- usage
- exit 1
- ;;
- l)
- echo "Available mirrors:"
- for name in ${MIRRORLIST} ; do
- echo " ${name}"
- done
- exit 0
- ;;
- n)
- NOOP=" (DRY RUN)"
- EXTRA_OPTS="${EXTRA_OPTS} -n"
- ;;
- *)
- usage
- exit 1
- ;;
- esac
-done
-
-shift "$((OPTIND - 1))"
-
-if [ $# -gt 0 ]; then
- for mirror in "$@" ; do
- if [ ! -f "${CONFDIR}/$1.conf" ]; then
- echo "ERR: No mirror named [$1]" 1>&2
- exit 1
- fi
- SYNC="${MIRRORS} $1"
- shift
- done
-else
- SYNC="${MIRRORLIST}"
-fi
-
-if [ "$(whoami)" != "mirror" ]; then
- echo "ERR: Script needs to be run as mirror user" 1>&2
- exit 1
-fi
-
-umask 022
-
-if [ -f "${LOCKFILE}" ]; then
- if kill -0 "$(cat ${LOCKFILE})" ; then
- STARTED=" ($(stat --format='%y' ${LOCKFILE}))"
- echo "ERR: Lockfile exists${STARTED}, exiting" 1>&2
- exit 1
- else
- echo "WARN: Removing stale lock file..." 1>&2
- rm -f "${LOCKFILE}"
- fi
-fi
-trap 'rm -f ${LOCKFILE}' INT TERM EXIT
-echo "$$" > "${LOCKFILE}"
-
-for mirror in ${SYNC} ; do
- POSTCMD=""
- SRC=""
- RSYNCOPTS=""
- . "${CONFDIR}/${mirror}.conf"
- if [ "${SRC}" = "" ]; then
- echo "ERR: No SRC set for mirror ${mirror} ..." 1>&2
- exit 1
- fi
- logmsg "Starting ${mirror} sync${NOOP}..."
- rsync -aH -4 ${EXTRA_OPTS} --numeric-ids --delete --delete-delay \
- --delay-updates --no-motd ${RSYNCOPTS} --log-file="${LOGFILE}" \
- --exclude=.~tmp~/ "${SRC}" "/srv/mirrors/${mirror}/"
- STATUS=$?
- if [ ${STATUS} -ne 0 ]; then
- echo "WARN: Encountered errors on ${mirror} sync, see ${LOGFILE} for details" 1>&2
- fi
- logmsg "Finished ${mirror} sync with exit status ${STATUS}${NOOP} ..."
- if [ "${POSTCMD}" != "" ]; then
- logmsg "Running post for ${mirror} ..."
- if [ "${VERBOSE}" -eq 1 ]; then
- ${POSTCMD} 2>&1 | tee >( \
- awk "{ print strftime(\"%Y/%m/%d %H:%M:%S\") \" [$$] \" \$0 }" \
- >> "${LOGFILE}" )
- else
- ${POSTCMD} 2>&1 | \
- awk "{ print strftime(\"%Y/%m/%d %H:%M:%S\") \" [$$] \" \$0 }" \
- >> "${LOGFILE}"
- fi
- logmsg "Finished post for ${mirror} ..."
- fi
-done
-
-rm -f "${LOCKFILE}"
diff --git a/roles/mirror/base/files/sync-mirrors.sh b/roles/mirror/base/files/sync-mirrors.sh
new file mode 100755
index 0000000..2dba204
--- /dev/null
+++ b/roles/mirror/base/files/sync-mirrors.sh
@@ -0,0 +1,125 @@
+#!/bin/sh
+
+set -eu
+umask 022
+
+LOCKFILE="/var/run/sync-mirrors/lockfile"
+LOGFILE="/var/log/sync-mirrors/sync-mirrors-$(date +%Y%m%d%H%M%S).log"
+CONFDIR="/etc/sync-mirrors"
+
+usage() {
+ echo "Usage: $(basename "$0") [-v] [mirror]" 1>&2
+ echo " $(basename "$0") -l" 1>&2
+}
+
+list_mirrors() {
+ for f in "$CONFDIR"/*.conf ; do
+ basename "$f" ".conf"
+ done
+}
+
+logmsg() {
+ "$VERBOSE" && echo "$1"
+ echo "$(date '+%Y/%m/%d %H:%M:%S') [$$] $1" >> "$LOGFILE"
+}
+
+logstream() {
+ while read -r line; do
+ logmsg "$line"
+ done
+}
+
+if [ ! -d "$CONFDIR" ]; then
+ echo "ERR: Config directory [${CONFDIR}] missing" 1>&2
+ exit 1
+fi
+
+VERBOSE=false
+NOOP=""
+EXTRA_OPTS=""
+while getopts "vhln" c ; do
+ case $c in
+ v)
+ VERBOSE=true
+ EXTRA_OPTS="${EXTRA_OPTS} -v --progress"
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ l)
+ echo "Available mirrors:"
+ list_mirrors | sed -e 's/^/ /'
+ exit 0
+ ;;
+ n)
+ NOOP=" (DRY RUN)"
+ EXTRA_OPTS="${EXTRA_OPTS} -n"
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+done
+
+shift "$((OPTIND - 1))"
+
+if [ $# -eq 0 ]; then
+ set -- $(list_mirrors)
+ if [ $# -eq 0 ]; then
+ echo "ERR: No configured mirrors found" 1>&2
+ exit 1
+ fi
+else
+ for mirror in "$@" ; do
+ if [ ! -f "${CONFDIR}/$1.conf" ]; then
+ echo "ERR: No mirror named [$1]" 1>&2
+ exit 1
+ fi
+ done
+fi
+
+if [ "$(whoami)" != "mirror" ]; then
+ echo "ERR: Script needs to be run as mirror user" 1>&2
+ exit 1
+fi
+
+if [ -f "$LOCKFILE" ]; then
+ if kill -0 "$(cat $LOCKFILE)" ; then
+ STARTED=" ($(stat --format='%y' $LOCKFILE))"
+ echo "ERR: Lockfile exists${STARTED}, exiting" 1>&2
+ exit 1
+ else
+ echo "WARN: Removing stale lock file..." 1>&2
+ rm -f "$LOCKFILE"
+ fi
+fi
+trap 'rm -f $LOCKFILE' INT TERM EXIT
+echo "$$" > "$LOCKFILE"
+
+for mirror in "$@" ; do
+ POSTCMD=""
+ SRC=""
+ RSYNCOPTS=""
+ # shellcheck source=/dev/null
+ . "${CONFDIR}/${mirror}.conf"
+ if [ "$SRC" = "" ]; then
+ echo "ERR: No SRC set for mirror ${mirror} ..." 1>&2
+ exit 1
+ fi
+ logmsg "Starting ${mirror} sync${NOOP}..."
+ rsync -aH -4 $EXTRA_OPTS --numeric-ids --delete --delete-delay \
+ --delay-updates --no-motd $RSYNCOPTS --log-file="$LOGFILE" \
+ --exclude=.~tmp~/ "$SRC" "/srv/mirrors/${mirror}/"
+ STATUS=$?
+ if [ $STATUS -ne 0 ]; then
+ echo "WARN: Encountered errors on ${mirror} sync, see ${LOGFILE} for details" 1>&2
+ fi
+ logmsg "Finished ${mirror} sync with exit status ${STATUS}${NOOP} ..."
+ if [ "$POSTCMD" != "" ]; then
+ logmsg "Running post for ${mirror} ..."
+ $POSTCMD 2>&1 | logstream
+ logmsg "Finished post for ${mirror} ..."
+ fi
+done
diff --git a/roles/mirror/base/tasks/main.yml b/roles/mirror/base/tasks/main.yml
index fbeeac4..c28f54b 100644
--- a/roles/mirror/base/tasks/main.yml
+++ b/roles/mirror/base/tasks/main.yml
@@ -7,7 +7,7 @@
- name: Create mirror group
ansible.builtin.group:
name: mirror
- gid: 1001
+ gid: 309
- name: Create mirror user
ansible.builtin.user:
@@ -17,13 +17,13 @@
group: mirror
home: /var/empty
shell: /sbin/nologin
- uid: 1001
+ uid: 309
- name: Create data directory
ansible.builtin.file:
path: /export/mirrors
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: root
@@ -44,7 +44,7 @@
ansible.builtin.file:
path: /etc/sync-mirrors
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: root
@@ -52,7 +52,7 @@
ansible.builtin.file:
path: "{{ item }}"
state: directory
- mode: 0755
+ mode: "0755"
owner: mirror
group: mirror
with_items:
@@ -63,18 +63,25 @@
ansible.builtin.copy:
dest: /usr/lib/tmpfiles.d/sync-mirrors.conf
content: "d /run/sync-mirrors 0755 mirror mirror\n"
- mode: 0644
+ mode: "0644"
owner: root
group: root
- name: Copy mirroring script
ansible.builtin.copy:
dest: /usr/local/bin/sync-mirrors
- src: sync-mirrors
- mode: 0755
+ src: sync-mirrors.sh
+ mode: "0755"
owner: root
group: root
+- name: Send cron mails to root
+ ansible.builtin.cron:
+ name: MAILTO
+ job: root
+ env: true
+ user: mirror
+
- name: Create mirror cron job
ansible.builtin.cron:
name: sync-mirrors
@@ -103,7 +110,7 @@
ansible.builtin.template:
src: mirror.conf.j2
dest: /etc/httpd/conf.local.d/mirror.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
diff --git a/roles/mirror/reportmirror/defaults/main.yml b/roles/mirror/reportmirror/defaults/main.yml
deleted file mode 100644
index c2ae745..0000000
--- a/roles/mirror/reportmirror/defaults/main.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-
-hostname: "{{ inventory_hostname }}"
-mirrors: []
diff --git a/roles/mirror/sync/defaults/main.yml b/roles/mirror/sync/defaults/main.yml
index 264336b..58b887d 100644
--- a/roles/mirror/sync/defaults/main.yml
+++ b/roles/mirror/sync/defaults/main.yml
@@ -1,3 +1,3 @@
---
-rsyncoptions: []
-postcmd: ""
+mirror_rsyncoptions: []
+mirror_postcmd: ""
diff --git a/roles/mirror/sync/tasks/main.yml b/roles/mirror/sync/tasks/main.yml
index ab8c46d..168271d 100644
--- a/roles/mirror/sync/tasks/main.yml
+++ b/roles/mirror/sync/tasks/main.yml
@@ -1,24 +1,24 @@
---
-- name: Create config for {{ label }}
+- name: Create config for {{ mirror_label }}
ansible.builtin.template:
- dest: "/etc/sync-mirrors/{{ label }}.conf"
+ dest: "/etc/sync-mirrors/{{ mirror_label }}.conf"
src: mirror.conf.j2
- mode: 0644
+ mode: "0644"
owner: root
group: root
- name: Create target directory
ansible.builtin.file:
- path: "/srv/mirrors/{{ label }}"
+ path: "/srv/mirrors/{{ mirror_label }}"
state: directory
- mode: 0755
+ mode: "0755"
owner: mirror
group: mirror
- name: Link target directory to web
ansible.builtin.file:
- path: "/srv/web/{{ inventory_hostname }}/{{ label }}"
- src: "/srv/mirrors/{{ label }}"
+ path: "/srv/web/{{ inventory_hostname }}/{{ mirror_label }}"
+ src: "/srv/mirrors/{{ mirror_label }}"
state: link
owner: mirror
group: mirror
diff --git a/roles/mirror/sync/templates/mirror.conf.j2 b/roles/mirror/sync/templates/mirror.conf.j2
index f605577..ab2b6ac 100644
--- a/roles/mirror/sync/templates/mirror.conf.j2
+++ b/roles/mirror/sync/templates/mirror.conf.j2
@@ -1,3 +1,3 @@
-SRC="{{ source }}"
-RSYNCOPTS="{{ rsyncoptions | join(' ') }}"
-POSTCMD="{{ postcmd }}"
+SRC="{{ mirror_source }}"
+RSYNCOPTS="{{ mirror_rsyncoptions | join(' ') }}"
+POSTCMD="{{ mirror_postcmd }}"
diff --git a/roles/mkhomedir/tasks/main.yml b/roles/mkhomedir/tasks/main.yml
index eac4cc3..7ec1627 100644
--- a/roles/mkhomedir/tasks/main.yml
+++ b/roles/mkhomedir/tasks/main.yml
@@ -5,11 +5,15 @@
state: installed
- name: Get current state of authselect
- ansible.builtin.shell:
- cmd: /usr/bin/authselect current --raw ; /bin/true
+ ansible.builtin.command:
+ argv:
+ - /usr/bin/authselect
+ - current
+ - "--raw"
register: result
check_mode: false
changed_when: false
+ failed_when: result.rc not in [0, 2]
- name: Enable mkhomedir
ansible.builtin.command:
diff --git a/roles/mod_auth_gssapi/tasks/main.yml b/roles/mod_auth_gssapi/tasks/main.yml
index 621726e..029c374 100644
--- a/roles/mod_auth_gssapi/tasks/main.yml
+++ b/roles/mod_auth_gssapi/tasks/main.yml
@@ -15,7 +15,7 @@
ansible.builtin.file:
path: /etc/systemd/system/httpd.service.d
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -23,7 +23,7 @@
ansible.builtin.copy:
dest: /etc/systemd/system/httpd.service.d/keytab.conf
content: "[Service]\nEnvironment=KRB5_KTNAME=/etc/httpd/httpd.keytab\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart apache
diff --git a/roles/mongodb/meta/main.yml b/roles/mongodb/meta/main.yml
new file mode 100644
index 0000000..f178512
--- /dev/null
+++ b/roles/mongodb/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: backup_base}
diff --git a/roles/mongodb/tasks/main.yml b/roles/mongodb/tasks/main.yml
index 2004130..582b32c 100644
--- a/roles/mongodb/tasks/main.yml
+++ b/roles/mongodb/tasks/main.yml
@@ -17,10 +17,11 @@
- name: Enable repository
ansible.builtin.yum_repository:
name: mongodb
- baseurl: https://repo.mongodb.org/yum/redhat/8/mongodb-org/5.0/x86_64
+ baseurl: >-
+ https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/6.0/x86_64
description: MongoDB
gpgcheck: true
- gpgkey: https://www.mongodb.org/static/pgp/server-5.0.asc
+ gpgkey: https://www.mongodb.org/static/pgp/server-6.0.asc
enabled: true
- name: Install packages
@@ -28,8 +29,9 @@
name: "{{ item }}"
state: installed
with_items:
+ - mongodb-database-tools
+ - mongodb-mongosh
- mongodb-org-server
- - mongodb-org-shell
- name: Set SELinux file contexts on data directory
community.general.sefcontext:
@@ -40,7 +42,7 @@
ansible.builtin.file:
path: /export/mongodb
state: directory
- mode: 0700
+ mode: "0700"
owner: mongod
group: mongod
setype: _default
@@ -61,13 +63,14 @@
- "{{ tls_certs }}/{{ inventory_hostname }}.crt"
- "{{ tls_private }}/{{ inventory_hostname }}.key"
changed_when: false
+ check_mode: false
register: mongodb_cert_key
- name: Create combined certificate/private key file
ansible.builtin.copy:
dest: "{{ tls_private }}/mongodb.pem"
content: "{{ mongodb_cert_key.stdout }}"
- mode: 0640
+ mode: "0640"
owner: root
group: mongod
notify: Restart mongod
@@ -76,25 +79,45 @@
ansible.builtin.copy:
dest: /etc/logrotate.d/mongod
src: mongod.logrotate
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
+- name: Create configuration directory
+ ansible.builtin.file:
+ path: /etc/mongod
+ state: directory
+ mode: "0750"
+ owner: root
+ group: mongod
+
+- name: Copy keyfile
+ ansible.builtin.copy:
+ dest: /etc/mongod/mongod.key
+ src: "{{ ansible_private }}/files/mongod/mongod.key"
+ mode: "0400"
+ owner: mongod
+ group: mongod
+ notify: Restart mongod
+
- name: Configure startup options
ansible.builtin.copy:
dest: /etc/sysconfig/mongod
content: |
- OPTIONS="-f /etc/mongod.conf --logRotate reopen"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- notify: Restart mongod
-
-- name: Create configuration
- ansible.builtin.template:
- dest: /etc/mongod.conf
- src: mongod.conf.j2
- mode: 0644
+ OPTIONS="-f /etc/mongod.conf \
+ --auth \
+ --bind_ip_all \
+ --dbpath /srv/mongodb \
+ --keyFile /etc/mongod/mongod.key \
+ --logRotate reopen \
+ --nounixsocket
+ --replSet rs0 \
+ --maxConns 16384 \
+ --tlsMode requireTLS \
+ --tlsCertificateKeyFile {{ tls_private }}/mongodb.pem
+ --tlsCAFile {{ tls_certs }}/ca.crt
+ --tlsDisabledProtocols TLS1_0,TLS1_1,TLS1_2"
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart mongod
@@ -105,12 +128,30 @@
state: started
enabled: true
+- name: Copy backup script
+ ansible.builtin.template:
+ dest: /usr/local/sbin/mongodb-backup
+ src: mongodb-backup.sh.j2
+ mode: "0700"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create backup cron job
+ ansible.builtin.cron:
+ name: mongodb-backup
+ job: /usr/local/sbin/mongodb-backup
+ hour: "0"
+ minute: "20"
+ user: root
+
- name: Create mongo alias cmd for root
ansible.builtin.lineinfile:
path: /root/.bashrc
line: >
- alias mongo='mongo
+ alias mongosh='mongosh
--tlsCertificateKeyFile {{ tls_private }}/mongodb.pem
--tlsCAFile {{ tls_certs }}/ca.crt
+ --username root
+ --password {{ mongodb_root_password }}
--tls mongodb://{{ inventory_hostname }}/'
- regexp: ^alias mongo=.*
+ regexp: ^alias mongosh=.*
diff --git a/roles/mongodb/templates/mongod.conf.j2 b/roles/mongodb/templates/mongod.conf.j2
deleted file mode 100644
index a05d000..0000000
--- a/roles/mongodb/templates/mongod.conf.j2
+++ /dev/null
@@ -1,23 +0,0 @@
-
-systemLog:
- destination: file
- logAppend: true
- path: /var/log/mongodb/mongod.log
-
-storage:
- dbPath: /srv/mongodb
- journal:
- enabled: true
-
-processManagement:
- fork: true
- pidFilePath: /var/run/mongodb/mongod.pid
- timeZoneInfo: /usr/share/zoneinfo
-
-net:
- port: 27017
- bindIpAll: true
- tls:
- mode: requireTLS
- certificateKeyFile: /etc/pki/tls/private/mongodb.pem
- CAFile: {{ tls_certs }}/ca.crt
diff --git a/roles/mongodb/templates/mongodb-backup.sh.j2 b/roles/mongodb/templates/mongodb-backup.sh.j2
new file mode 100755
index 0000000..fc415e8
--- /dev/null
+++ b/roles/mongodb/templates/mongodb-backup.sh.j2
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -eu
+
+umask 027
+
+DESTDIR="/srv/backup"
+DATE="$(date +%Y-%m-%d)"
+
+cd "$DESTDIR"
+find . -xdev -mindepth 3 -maxdepth 3 -type f -mtime +30 \
+ -execdir rm -f -- {} \;
+find . -xdev -depth -mindepth 1 -maxdepth 2 -type d -empty \
+ -execdir rmdir -- {} \;
+
+mkdir -m 2750 "$DATE"
+chgrp backup "$DATE"
+
+mongodump \
+ --sslPEMKeyFile=/etc/pki/tls/private/mongodb.pem \
+ --sslCAFile=/etc/pki/tls/certs/ca.crt \
+ --ssl \
+ --username=backup \
+ --password="{{ mongodb_backup_password }}" \
+ --gzip \
+ --out="${DATE}" \
+ --quiet \
+ --uri="mongodb://$(hostname -f)/"
diff --git a/roles/mosquitto/files/acl.conf b/roles/mosquitto/files/acl.conf
new file mode 100644
index 0000000..aa76e34
--- /dev/null
+++ b/roles/mosquitto/files/acl.conf
@@ -0,0 +1,7 @@
+topic deny #
+
+user shellyplug-s-*
+pattern write shellies/%u/#
+
+user shellydw2-*
+pattern write shellies/%u/#
diff --git a/roles/mosquitto/files/mosquitto_tls.ksh b/roles/mosquitto/files/mosquitto_tls.ksh
new file mode 100644
index 0000000..9481c35
--- /dev/null
+++ b/roles/mosquitto/files/mosquitto_tls.ksh
@@ -0,0 +1,10 @@
+#!/bin/ksh
+
+# shellcheck disable=SC2034
+daemon="/usr/local/sbin/mosquitto -d"
+daemon_flags="-c /etc/mosquitto-tls/mosquitto.conf"
+
+# shellcheck source=/dev/null
+. /etc/rc.d/rc.subr
+
+rc_cmd "$1"
diff --git a/roles/mosquitto/handlers/main.yml b/roles/mosquitto/handlers/main.yml
index 7e1bb2c..268abc3 100644
--- a/roles/mosquitto/handlers/main.yml
+++ b/roles/mosquitto/handlers/main.yml
@@ -3,3 +3,8 @@
ansible.builtin.service:
name: mosquitto
state: restarted
+
+- name: Restart mosquitto-tls
+ ansible.builtin.service:
+ name: mosquitto_tls
+ state: restarted
diff --git a/roles/mosquitto/tasks/main.yml b/roles/mosquitto/tasks/main.yml
index 44a1681..d405371 100644
--- a/roles/mosquitto/tasks/main.yml
+++ b/roles/mosquitto/tasks/main.yml
@@ -9,15 +9,21 @@
name: _mosquitto
groups: hostkey
append: true
- notify: Restart mosquitto
+ notify:
+ - Restart mosquitto
+ - Restart mosquitto-tls
-- name: Create include directory for config
+- name: Create config directories
ansible.builtin.file:
- path: /etc/mosquitto/conf.d
+ path: "{{ item }}"
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: _mosquitto
+ with_items:
+ - /etc/mosquitto/conf.d
+ - /etc/mosquitto-tls
+ - /etc/mosquitto-tls/conf.d
- name: Include extra configs
ansible.builtin.lineinfile:
@@ -26,35 +32,84 @@
regexp: "^#?include_dir( .*)?$"
notify: Restart mosquitto
-- name: Create custom config
+- name: Create custom config for plaintext server
ansible.builtin.template:
dest: /etc/mosquitto/conf.d/local.conf
src: mosquitto.conf.j2
- mode: 0640
+ mode: "0640"
owner: root
group: _mosquitto
notify: Restart mosquitto
-- name: Copy acl file
+- name: Copy acl file for plaintext server
ansible.builtin.copy:
dest: /etc/mosquitto/acl.conf
- src: "{{ ansible_private }}/files/mosquitto/acl.conf"
- mode: 0640
- owner: root
+ src: acl.conf
+ mode: "0400"
+ owner: _mosquitto
group: _mosquitto
notify: Restart mosquitto
-- name: Copy passwd file
+- name: Copy passwd file for plaintext server
ansible.builtin.copy:
dest: /etc/mosquitto/passwd
src: "{{ ansible_private }}/files/mosquitto/passwd"
- mode: 0640
- owner: root
+ mode: "0400"
+ owner: _mosquitto
group: _mosquitto
notify: Restart mosquitto
-- name: Enable service
+- name: Create default config for tls server
+ ansible.builtin.command:
+ argv:
+ - sed
+ - "s|^include_dir .*|include_dir /etc/mosquitto-tls/conf.d|"
+ - /etc/mosquitto/mosquitto.conf
+ changed_when: false
+ register: result
+
+- name: Write default config for tls server
+ ansible.builtin.copy:
+ dest: /etc/mosquitto-tls/mosquitto.conf
+ content: "{{ result.stdout }}\n"
+ mode: "0640"
+ owner: root
+ group: _mosquitto
+ remote_src: true
+ notify: Restart mosquitto-tls
+
+- name: Create custom config for tls server
+ ansible.builtin.template:
+ dest: /etc/mosquitto-tls/conf.d/local.conf
+ src: mosquitto-tls.conf.j2
+ mode: "0640"
+ owner: root
+ group: _mosquitto
+ notify: Restart mosquitto-tls
+
+- name: Create acl file for tls server
+ ansible.builtin.template:
+ dest: /etc/mosquitto-tls/acl.conf
+ src: acl-tls.conf.j2
+ mode: "0400"
+ owner: _mosquitto
+ group: _mosquitto
+ notify: Restart mosquitto-tls
+
+- name: Create mosquitto-tls control script
+ ansible.builtin.copy:
+ dest: /etc/rc.d/mosquitto_tls
+ src: mosquitto_tls.ksh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart mosquitto-tls
+
+- name: Enable services
ansible.builtin.service:
- name: mosquitto
+ name: "{{ item }}"
enabled: true
state: started
+ with_items:
+ - mosquitto
+ - mosquitto_tls
diff --git a/roles/mosquitto/templates/acl-tls.conf.j2 b/roles/mosquitto/templates/acl-tls.conf.j2
new file mode 100644
index 0000000..7422313
--- /dev/null
+++ b/roles/mosquitto/templates/acl-tls.conf.j2
@@ -0,0 +1,10 @@
+pattern read #
+
+user {{ inventory_hostname }}
+topic readwrite #
+
+user nms*.home.foo.sh
+pattern readwrite #
+
+user frigate*.home.foo.sh
+pattern readwrite frigate/%u/#
diff --git a/roles/mosquitto/templates/mosquitto-tls.conf.j2 b/roles/mosquitto/templates/mosquitto-tls.conf.j2
new file mode 100644
index 0000000..7cf1712
--- /dev/null
+++ b/roles/mosquitto/templates/mosquitto-tls.conf.j2
@@ -0,0 +1,11 @@
+listener 8883
+protocol mqtt
+
+certfile {{ tls_certs }}/{{ inventory_hostname }}.crt
+keyfile {{ tls_private }}/{{ inventory_hostname }}.key
+cafile {{ tls_certs }}/ca.crt
+tls_version tlsv1.3
+
+acl_file /etc/mosquitto-tls/acl.conf
+require_certificate true
+use_identity_as_username true
diff --git a/roles/mosquitto/templates/mosquitto.conf.j2 b/roles/mosquitto/templates/mosquitto.conf.j2
index f0bc82a..4232fba 100644
--- a/roles/mosquitto/templates/mosquitto.conf.j2
+++ b/roles/mosquitto/templates/mosquitto.conf.j2
@@ -1,17 +1,21 @@
-# authentication
+listener 1883
+protocol mqtt
+
acl_file /etc/mosquitto/acl.conf
password_file /etc/mosquitto/passwd
allow_anonymous false
-# listen to mqtt
-listener 1883
-protocol mqtt
+connection tls-bridge
+address {{ inventory_hostname }}:8883
+bridge_cafile {{ tls_certs }}/ca.crt
+bridge_certfile {{ tls_certs }}/{{ inventory_hostname }}.crt
+bridge_keyfile {{ tls_private }}/{{ inventory_hostname }}.key
-# listen to mqtt over websockets
-listener 8883
-protocol websockets
-
-# tls options
-certfile {{ tls_certs }}/{{ inventory_hostname }}.crt
-keyfile {{ tls_private }}/{{ inventory_hostname }}.key
-cafile {{ tls_certs }}/ca.crt
+{% for shelly in shellies %}
+{% if shelly['name'] | regex_search("^shellyplug-s-") %}
+topic power out 0 shellies/{{ shelly['name'] }}/relay/0/ home/{{ shelly['room'] }}/{{ shelly['device'] }}/
+topic temperature out 0 shellies/{{ shelly['name'] }}/ home/{{ shelly['room'] }}/{{ shelly['device'] }}/
+{% else %}
+topic # out 0 shellies/{{ shelly['name'] }}/ home/{{ shelly['room'] }}/{{ shelly['device'] }}/
+{% endif %}
+{% endfor %}
diff --git a/roles/mysqld_exporter/defaults/main.yml b/roles/mysqld_exporter/defaults/main.yml
new file mode 100644
index 0000000..77a7507
--- /dev/null
+++ b/roles/mysqld_exporter/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+mysqld_exporter_pkg: "mysqld_exporter-{{ mysqld_exporter_version }}.linux-amd64"
diff --git a/roles/mysqld_exporter/files/mysqld_exporter.service b/roles/mysqld_exporter/files/mysqld_exporter.service
new file mode 100644
index 0000000..c623707
--- /dev/null
+++ b/roles/mysqld_exporter/files/mysqld_exporter.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Prometheus MySQL Exporter
+After=syslog.target
+After=network.target
+
+[Service]
+Type=simple
+User=mysqld_exporter
+Group=mysqld_exporter
+ExecStart=/usr/local/bin/mysqld_exporter --config.my-cnf=/etc/mysqld_exporter/my.cnf --web.config.file=/etc/mysqld_exporter/web-config.yml
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/mysqld_exporter/handlers/main.yml b/roles/mysqld_exporter/handlers/main.yml
new file mode 100644
index 0000000..855013c
--- /dev/null
+++ b/roles/mysqld_exporter/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart mysqld_exporter
+ ansible.builtin.systemd:
+ name: mysqld_exporter
+ daemon_reload: true
+ state: restarted
diff --git a/roles/mysqld_exporter/meta/main.yml b/roles/mysqld_exporter/meta/main.yml
new file mode 100644
index 0000000..9978a00
--- /dev/null
+++ b/roles/mysqld_exporter/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: pki}
diff --git a/roles/mysqld_exporter/tasks/main.yml b/roles/mysqld_exporter/tasks/main.yml
new file mode 100644
index 0000000..d8722d1
--- /dev/null
+++ b/roles/mysqld_exporter/tasks/main.yml
@@ -0,0 +1,88 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: mysqld_exporter
+ system: true
+
+- name: Create user
+ ansible.builtin.user:
+ name: mysqld_exporter
+ comment: Prometheus MySQL Exporter
+ group: mysqld_exporter
+ groups: hostkey
+ create_home: false
+ home: /var/empty
+ shell: /sbin/nologin
+ system: true
+
+- name: Download package
+ ansible.builtin.get_url:
+ url: >-
+ {{
+ "https://github.com/prometheus/mysqld_exporter/releases/download/v"
+ + mysqld_exporter_version + "/" + mysqld_exporter_pkg + ".tar.gz"
+ }}
+ dest: "/usr/local/src/{{ mysqld_exporter_pkg }}.tar.gz"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Extract package
+ ansible.builtin.unarchive:
+ src: "/usr/local/src/{{ mysqld_exporter_pkg }}.tar.gz"
+ dest: /usr/local/src
+ owner: root
+ group: "{{ ansible_wheel }}"
+ creates: "/usr/local/src/{{ mysqld_exporter_pkg }}"
+ remote_src: true
+
+- name: Copy binary
+ ansible.builtin.copy:
+ dest: /usr/local/bin/mysqld_exporter
+ src: "/usr/local/src/{{ mysqld_exporter_pkg }}/mysqld_exporter"
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ remote_src: true
+ notify: Restart mysqld_exporter
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/mysqld_exporter
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create web-config
+ ansible.builtin.template:
+ dest: /etc/mysqld_exporter/web-config.yml
+ src: web-config.yml.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart mysqld_exporter
+
+- name: Create credentials config
+ ansible.builtin.template:
+ dest: /etc/mysqld_exporter/my.cnf
+ src: my.cnf.j2
+ mode: "0640"
+ owner: root
+ group: mysqld_exporter
+ notify: Restart mysqld_exporter
+
+- name: Create service file
+ ansible.builtin.copy:
+ dest: /etc/systemd/system/mysqld_exporter.service
+ src: mysqld_exporter.service
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart mysqld_exporter
+
+- name: Enable service
+ ansible.builtin.service:
+ name: mysqld_exporter
+ state: started
+ enabled: true
diff --git a/roles/mysqld_exporter/templates/my.cnf.j2 b/roles/mysqld_exporter/templates/my.cnf.j2
new file mode 100644
index 0000000..2627e84
--- /dev/null
+++ b/roles/mysqld_exporter/templates/my.cnf.j2
@@ -0,0 +1,6 @@
+[client]
+user = mysqld_exporter
+password = {{ mysqld_exporter_pass }}
+ssl-cert = {{ tls_certs }}/{{ inventory_hostname }}.crt
+ssl-key = {{ tls_private }}/{{ inventory_hostname }}.key
+ssl-ca = {{ tls_certs }}/ca.crt
diff --git a/roles/mysqld_exporter/templates/web-config.yml.j2 b/roles/mysqld_exporter/templates/web-config.yml.j2
new file mode 100644
index 0000000..25b4d05
--- /dev/null
+++ b/roles/mysqld_exporter/templates/web-config.yml.j2
@@ -0,0 +1,10 @@
+tls_server_config:
+ key_file: {{ tls_private }}/{{ inventory_hostname }}.key
+ cert_file: {{ tls_certs }}/{{ inventory_hostname }}.crt
+ client_ca_file: {{ tls_certs }}/ca.crt
+ client_auth_type: RequireAndVerifyClientCert
+ client_allowed_sans:
+{% for host in groups['prometheus'] %}
+ - {{ host }}
+{% endfor %}
+ min_version: TLS13
diff --git a/roles/network/files/keepalived-notify.sh b/roles/network/files/keepalived-notify.sh
new file mode 100755
index 0000000..bd709f9
--- /dev/null
+++ b/roles/network/files/keepalived-notify.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -eu
+
+umask 022
+
+echo "$3" > "/run/keepalived/${2}.state"
diff --git a/roles/network/handlers/main.yml b/roles/network/handlers/main.yml
index 290312a..945ccb9 100644
--- a/roles/network/handlers/main.yml
+++ b/roles/network/handlers/main.yml
@@ -12,6 +12,13 @@
- c
- reload
+- name: Refresh keepalived run directory
+ ansible.builtin.command:
+ argv:
+ - systemd-tmpfiles
+ - --create
+ - /etc/tmpfiles.d/keepalived.conf
+
- name: Restart keepalived
ansible.builtin.service:
name: keepalived
diff --git a/roles/network/tasks/OpenBSD.yml b/roles/network/tasks/OpenBSD.yml
index 6c2a5ac..f28a5be 100644
--- a/roles/network/tasks/OpenBSD.yml
+++ b/roles/network/tasks/OpenBSD.yml
@@ -3,7 +3,7 @@
ansible.builtin.template:
src: hostname.if.j2
dest: "/etc/hostname.{{ item.device }}"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
with_items: "{{ network_interfaces }}"
@@ -13,7 +13,7 @@
ansible.builtin.template:
src: hostname.carp.j2
dest: "/etc/hostname.carp{{ item.vhid }}"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
with_items: "{{ network_vip_interfaces }}"
@@ -34,7 +34,7 @@
ansible.builtin.copy:
content: "{{ network_default_gateway }}\n"
dest: /etc/mygate
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart network
diff --git a/roles/network/tasks/RedHat.yml b/roles/network/tasks/RedHat.yml
index 19b71da..92b38c9 100644
--- a/roles/network/tasks/RedHat.yml
+++ b/roles/network/tasks/RedHat.yml
@@ -15,11 +15,27 @@
ansible.builtin.template:
src: ifcfg-eth.j2
dest: "/etc/sysconfig/network-scripts/ifcfg-{{ item.device }}"
- mode: 0644
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ # notify: Reload network manager connections
+ with_items: "{{ network_interfaces }}"
+ when:
+ - ansible_distribution != "Fedora"
+ - ansible_distribution_major_version | int <= 8
+
+- name: Create ethernet interface configurations
+ ansible.builtin.template:
+ src: nmconnection.j2
+ dest: "/etc/NetworkManager/system-connections/{{ item.device }}.nmconnection"
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Reload network manager connections
with_items: "{{ network_interfaces }}"
+ when: >-
+ ansible_distribution == "Fedora" or
+ ansible_distribution_major_version | int >= 9
- name: Install keepalived
ansible.builtin.package:
@@ -29,11 +45,55 @@
- network_vip_interfaces is defined
- network_vip_interfaces != []
+- name: Create keepalived group
+ ansible.builtin.group:
+ name: keepalived
+ system: true
+ when:
+ - network_vip_interfaces is defined
+ - network_vip_interfaces != []
+
+- name: Create keepalived user
+ ansible.builtin.user:
+ name: keepalived
+ comment: Service keepalived
+ createhome: false
+ group: keepalived
+ home: /var/empty
+ shell: /sbin/nologin
+ system: true
+ when:
+ - network_vip_interfaces is defined
+ - network_vip_interfaces != []
+
+- name: Create run directory
+ ansible.builtin.copy:
+ dest: /etc/tmpfiles.d/keepalived.conf
+ content: "d /run/keepalived 755 keepalived keepalived"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Refresh keepalived run directory
+ when:
+ - network_vip_interfaces is defined
+ - network_vip_interfaces != []
+
+- name: Copy keepalived notify script
+ ansible.builtin.copy:
+ dest: /usr/local/libexec/keepalived-notify
+ src: keepalived-notify.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ when:
+ - network_vip_interfaces is defined
+ - network_vip_interfaces != []
+
- name: Create keepalived config
ansible.builtin.template:
dest: /etc/keepalived/keepalived.conf
src: keepalived.conf.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart keepalived
diff --git a/roles/network/tasks/main.yml b/roles/network/tasks/main.yml
index 6f9d8b6..83d8005 100644
--- a/roles/network/tasks/main.yml
+++ b/roles/network/tasks/main.yml
@@ -1,12 +1,3 @@
---
- name: Include OS spcific tasks
ansible.builtin.include_tasks: "{{ ansible_os_family }}.yml"
-
-- name: Create resolv.conf
- ansible.builtin.template:
- src: resolv.conf.j2
- dest: /etc/resolv.conf
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- when: network_dns_servers is defined
diff --git a/roles/network/templates/hostname.if.j2 b/roles/network/templates/hostname.if.j2
index 0db5d8b..862640b 100644
--- a/roles/network/templates/hostname.if.j2
+++ b/roles/network/templates/hostname.if.j2
@@ -1,3 +1,6 @@
+{% if item.rdomain is defined %}
+rdomain {{ item.rdomain }}
+{% endif %}
{% if item.proto is not defined or item.proto == 'dhcp' %}
dhcp
{% elif item.proto == 'static' %}
diff --git a/roles/network/templates/keepalived.conf.j2 b/roles/network/templates/keepalived.conf.j2
index 83c873b..c68642d 100644
--- a/roles/network/templates/keepalived.conf.j2
+++ b/roles/network/templates/keepalived.conf.j2
@@ -1,7 +1,8 @@
! {{ ansible_managed }}
global_defs {
-
+ enable_script_security
+ script_user keepalived
}
{% for vip in network_vip_interfaces %}
@@ -16,7 +17,8 @@ vrrp_instance VI_{{ vip.vhid }} {
auth_pass {{ vip.pass }}
}
virtual_ipaddress {
- {{ vip.ipaddr }}
+ {{ vip.ipaddr }}/{{ (vip.ipaddr + '/' + vip.netmask) | ansible.utils.ipaddr('prefix') }}
}
+ notify /usr/local/libexec/keepalived-notify
}
{% endfor %}
diff --git a/roles/network/templates/nmconnection.j2 b/roles/network/templates/nmconnection.j2
new file mode 100644
index 0000000..4a27ddb
--- /dev/null
+++ b/roles/network/templates/nmconnection.j2
@@ -0,0 +1,44 @@
+[connection]
+id={{ item.device }}
+{% for line in interface_uuid.stdout_lines %}
+{% if line.split()[0] == item.device %}
+uuid={{ line.split()[1] }}
+{% elif line.split()[2] == item.device %}
+uuid={{ line.split()[1] }}
+{% endif %}
+{% endfor %}
+type=ethernet
+interface-name={{ item.device }}
+
+[ethernet]
+
+[ipv4]
+{% if item.proto is not defined or item.proto == 'dhcp' %}
+method=auto
+{% elif item.proto == 'static' %}
+method=manual
+address1={{ item.ipaddr }}/{{ (item.ipaddr + '/' + item.netmask) | ansible.utils.ipaddr('prefix') }}
+{% if item.gateway is defined %}
+gateway={{ item.gateway }}
+{% endif %}
+{% elif item.proto == 'none' %}
+method=disabled
+{% endif %}
+{% if item.nameservers is defined and item.nameservers != [] %}
+dns={% for name in item.nameservers %}{{ name }};{% endfor %}
+
+dns-priority=-10
+{% endif %}
+
+[ipv6]
+addr-gen-mode=eui64
+{% if item.ip6addr is not defined or item.ip6addr == 'none' %}
+method=disabled
+{% elif item.ip6addr == 'auto' %}
+method=auto
+{% else %}
+method=manual
+address1={{ item.ip6addr }}
+{% endif %}
+
+[proxy]
diff --git a/roles/network/templates/resolv.conf.j2 b/roles/network/templates/resolv.conf.j2
deleted file mode 100644
index 0e8f587..0000000
--- a/roles/network/templates/resolv.conf.j2
+++ /dev/null
@@ -1,6 +0,0 @@
-{% if network_dns_search is defined %}
-search {{ network_dns_search|join(' ') }}
-{% endif %}
-{% for addr in network_dns_servers %}
-nameserver {{ addr }}
-{% endfor %}
diff --git a/roles/nfs_client/meta/main.yml b/roles/nfs_client/meta/main.yml
index 14a902c..b5c17d7 100644
--- a/roles/nfs_client/meta/main.yml
+++ b/roles/nfs_client/meta/main.yml
@@ -1,3 +1,4 @@
---
dependencies:
- {role: kerberos}
+ - {role: tlshd}
diff --git a/roles/nfs_client/tasks/main.yml b/roles/nfs_client/tasks/main.yml
index 0953d3a..06fe6d6 100644
--- a/roles/nfs_client/tasks/main.yml
+++ b/roles/nfs_client/tasks/main.yml
@@ -14,7 +14,7 @@
ansible.builtin.copy:
dest: /etc/modprobe.d/nfs.conf
content: "options nfs nfs4_disable_idmapping=0\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/nfs_server/files/exports b/roles/nfs_server/files/exports
new file mode 100644
index 0000000..51916e7
--- /dev/null
+++ b/roles/nfs_server/files/exports
@@ -0,0 +1,6 @@
+/export/home @nfsclients-rw(rw,root_squash,secure,xprtsec=mtls,sec=sys) \
+ @nfsclients-ro(ro,root_squash,secure,xprtsec=mtls,sec=sys) \
+ @nfsclients-krb(rw,root_squash,secure,xprtsec=mtls,sec=krb5p)
+/export/roles @nfsclients-rw(rw,root_squash,secure,xprtsec=mtls,sec=sys) \
+ @nfsclients-ro(ro,root_squash,secure,xprtsec=mtls,sec=sys) \
+ @nfsclients-krb(rw,root_squash,secure,xprtsec=mtls,sec=krb5p)
diff --git a/roles/nfs_server/files/local.conf b/roles/nfs_server/files/local.conf
new file mode 100644
index 0000000..b5085c3
--- /dev/null
+++ b/roles/nfs_server/files/local.conf
@@ -0,0 +1,7 @@
+[mountd]
+debug="auth,general"
+
+[nfsd]
+udp=n
+tcp=y
+vers3=n
diff --git a/roles/nfs_server/tasks/main.yml b/roles/nfs_server/tasks/main.yml
index 32b1701..8ac57b1 100644
--- a/roles/nfs_server/tasks/main.yml
+++ b/roles/nfs_server/tasks/main.yml
@@ -1,27 +1,34 @@
---
-- name: Disable NFS versions 2 and 3
- ansible.builtin.lineinfile:
- path: /etc/nfs.conf
- line: "{{ item }}=n"
- regexp: '^(#\s*)?{{ item }}=.*'
- with_items:
- - vers2
- - vers3
- notify: Restart nfs-server
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/nfs.conf.d
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
-- name: Disable NFS over UDP
- ansible.builtin.lineinfile:
- path: /etc/nfs.conf
- line: "udp=n"
- regexp: '^(#\s*)?udp=.*'
- insertbefore: vers2=n
+- name: Create local config
+ ansible.builtin.copy:
+ dest: /etc/nfs.conf.d/local.conf
+ src: local.conf
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create exports
+ ansible.builtin.copy:
+ dest: /etc/exports
+ src: exports
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
notify: Restart nfs-server
- name: Install home/role autocreate scripts
ansible.builtin.copy:
dest: "/usr/local/sbin/{{ item }}"
src: "{{ item }}.sh"
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
with_items:
diff --git a/roles/nftables/tasks/main.yml b/roles/nftables/tasks/main.yml
index f60342f..5069a93 100644
--- a/roles/nftables/tasks/main.yml
+++ b/roles/nftables/tasks/main.yml
@@ -13,9 +13,10 @@
ansible.builtin.template:
src: nftables.conf.j2
dest: /etc/sysconfig/nftables.conf
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
+ validate: "nft -c -f %s"
notify: Reload nftables
- name: Enable service
diff --git a/roles/nftables/templates/nftables.conf.j2 b/roles/nftables/templates/nftables.conf.j2
index 44f153c..067285c 100644
--- a/roles/nftables/templates/nftables.conf.j2
+++ b/roles/nftables/templates/nftables.conf.j2
@@ -8,6 +8,11 @@ table ip filter {
ct state vmap { established : accept, related : accept }
ip protocol icmp accept
iifname lo accept
+{% if firewall_raw is defined %}
+{% for rule in firewall_raw %}
+ {{ rule }}
+{% endfor %}
+{% endif %}
{% for rule in firewall_in %}
{% if rule.from is defined %}
{% for from in rule.from %}
@@ -35,6 +40,11 @@ table ip6 filter {
type filter hook input priority 0; policy accept
ct state vmap { established : accept, related : accept }
ip6 nexthdr icmpv6 accept
+{% if firewall_raw6 is defined %}
+{% for rule in firewall_raw6 %}
+ {{ rule }}
+{% endfor %}
+{% endif %}
{% for rule in firewall_in %}
{% if rule.from is defined %}
{% for from in rule.from %}
diff --git a/roles/nginx/server/files/dependency.conf b/roles/nginx/files/dependency.conf
similarity index 100%
rename from roles/nginx/server/files/dependency.conf
rename to roles/nginx/files/dependency.conf
diff --git a/roles/nginx/files/nginx-logrotate.sh b/roles/nginx/files/nginx-logrotate.sh
new file mode 100755
index 0000000..b7fc0cf
--- /dev/null
+++ b/roles/nginx/files/nginx-logrotate.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -eu
+
+cd /var/www/logs
+
+find_rotated() {
+ find . -mindepth 1 -maxdepth 1 -type f -name "${1}.*" | sort -V -r
+}
+
+for log in *.log ; do
+ find_rotated "$log" | while read -r name; do
+ ext="${name##*.}"
+ next="${name%.*}.$((ext+1))"
+ mv "$name" "$next"
+ done
+ mv "$log" "${log}.1"
+ touch "$log"
+
+ find_rotated "$log" | while read -r name; do
+ num="$(echo "$name" | awk -F. '{ print $NF }')"
+ if [ "$num" -gt 7 ]; then
+ rm -f "${log}.${num}"
+ fi
+ done
+done
+
+kill -USR1 "$(cat /var/run/nginx.pid)"
diff --git a/roles/nginx/server/handlers/main.yml b/roles/nginx/handlers/main.yml
similarity index 100%
rename from roles/nginx/server/handlers/main.yml
rename to roles/nginx/handlers/main.yml
diff --git a/roles/nginx/server/meta/main.yml b/roles/nginx/meta/main.yml
similarity index 100%
rename from roles/nginx/server/meta/main.yml
rename to roles/nginx/meta/main.yml
diff --git a/roles/nginx/site/tasks/main.yml b/roles/nginx/site/tasks/main.yml
deleted file mode 100644
index fbb2793..0000000
--- a/roles/nginx/site/tasks/main.yml
+++ /dev/null
@@ -1,47 +0,0 @@
----
-- name: "Create site data directory for {{ site }}"
- ansible.builtin.file:
- path: "/srv/web/{{ site }}"
- state: directory
- mode: 0755
- owner: root
- group: "{{ ansible_wheel }}"
- when: redirect is not defined and proxy is not defined
-
-- name: "Create site config for {{ site }}"
- ansible.builtin.template:
- dest: /etc/nginx/conf.d/{{ site }}.conf
- src: site.conf.j2
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- notify: Restart nginx
-
-- name: "Copy site private key for {{ site }}"
- ansible.builtin.copy:
- dest: "{{ tls_private }}/{{ site }}.key"
- src: "{{ item }}"
- mode: 0600
- owner: root
- group: "{{ ansible_wheel }}"
- with_first_found:
- - "/srv/letsencrypt/live/{{ site }}/privkey.pem"
- - "/srv/ca/private/{{ site }}.key"
- - "/srv/ca/private/{{ inventory_hostname }}.key"
- tags: certificates
- notify: Restart nginx
-
-- name: "Copy site certificate for {{ site }}"
- ansible.builtin.copy:
- src: "{{ item }}"
- dest: "{{ tls_certs }}/{{ site }}-fullchain.crt"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- validate: /usr/bin/openssl x509 -in %s -noout
- with_first_found:
- - "/srv/letsencrypt/live/{{ site }}/fullchain.pem"
- - "/srv/ca/certs/hosts/{{ site }}.crt"
- - "/srv/ca/certs/hosts/{{ inventory_hostname }}.crt"
- tags: certificates
- notify: Restart nginx
diff --git a/roles/nginx/site/templates/site.conf.j2 b/roles/nginx/site/templates/site.conf.j2
deleted file mode 100644
index a277ec5..0000000
--- a/roles/nginx/site/templates/site.conf.j2
+++ /dev/null
@@ -1,66 +0,0 @@
-{% if proxy is defined and proxy is not string %}
-upstream upstream-{{ site }} {
-{% for item in proxy %}
-{% set item = item | regex_replace("^(https://)?([^/]*).*$", "\\2") %}
-{% if item | regex_search(".*:[0-9]+$") %}
- server {{ item }};
-{% else %}
- server {{ item }}:443;
-{% endif %}
-{% endfor %}
-}
-{% endif %}
-server {
- listen 443 ssl http2;
- listen [::]:443 ssl http2;
- server_name {{ site }};
-
- access_log {{ nginx_logdir }}/{{ site }}.access.log combined;
- error_log {{ nginx_logdir }}/{{ site }}.error.log warn;
-
- add_header Strict-Transport-Security "max-age=63072000" always;
-
-{% if ssl_config is defined %}
-{% if ssl_config == "old" %}
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
- ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA;
- ssl_prefer_server_ciphers on;
-{% endif %}
-{% endif %}
- ssl_certificate {{ tls_certs }}/{{ site }}-fullchain.crt;
- ssl_certificate_key {{ tls_private }}/{{ site }}.key;
-
-{% include "./{}.conf.j2".format(site) ignore missing %}
-{% if redirect is defined %}
- return 301 {{ redirect }};
-{% elif proxy is defined %}
- location / {
-{% if proxy is not string %}
-{% set path = proxy[0] | regex_replace("^(https://)?([^/]*)(.*)$", "\\3") %}
- # https://trac.nginx.org/nginx/ticket/1307
- proxy_ssl_verify off;
- proxy_pass https://upstream-{{ site }}{{ path }};
-{% else %}
- proxy_pass {{ proxy }};
-{% endif %}
- }
-{% else %}
- root /srv/web/{{ site }};
-{% endif %}
-}
-
-server {
- listen 80;
- listen [::]:80;
- server_name {{ site }};
- location /.well-known/acme-challenge/ {
- proxy_pass https://certbot.home.foo.sh/.well-known/acme-challenge/;
- }
- location / {
-{% if redirect is defined %}
- return 301 {{ redirect }};
-{% else %}
- return 301 https://$host$request_uri;
-{% endif %}
- }
-}
diff --git a/roles/nginx/server/tasks/main.yml b/roles/nginx/tasks/main.yml
similarity index 69%
rename from roles/nginx/server/tasks/main.yml
rename to roles/nginx/tasks/main.yml
index 33fc042..a397adf 100644
--- a/roles/nginx/server/tasks/main.yml
+++ b/roles/nginx/tasks/main.yml
@@ -2,18 +2,19 @@
- name: Include OS-specific variables
ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
-- name: Enable nginx:120 module
+- name: Enable nginx:124 module
ansible.builtin.command:
argv:
- dnf
- module
- -y
- enable
- - nginx:1.20
+ - nginx:1.24
creates: /etc/dnf/modules.d/nginx.module
+ notify: Restart nginx
when:
- ansible_os_family == "RedHat"
- - ansible_distribution_major_version | int == 8
+ - ansible_distribution_major_version | int >= 9
- ansible_distribution != "Fedora"
- name: Install packages
@@ -31,7 +32,7 @@
ansible.builtin.file:
state: directory
path: "{{ item }}"
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
seuser: _default
@@ -45,7 +46,7 @@
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
@@ -55,7 +56,7 @@
ansible.builtin.file:
dest: /etc/systemd/system/nginx.service.d
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
when: ansible_os_family == "RedHat"
@@ -64,11 +65,35 @@
ansible.builtin.copy:
dest: /etc/systemd/system/nginx.service.d/dependency.conf
src: dependency.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
when: ansible_os_family == "RedHat"
+- name: Disable web logs from newsyslog
+ ansible.builtin.replace:
+ path: /etc/newsyslog.conf
+ regexp: "^/var/www/logs/"
+ replace: "#/var/www/logs/"
+ when: ansible_system == "OpenBSD"
+
+- name: Install logrotate script
+ ansible.builtin.copy:
+ dest: /usr/local/bin/nginx-logrotate
+ src: nginx-logrotate.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ when: ansible_system == "OpenBSD"
+
+- name: Add logrotate cron job
+ ansible.builtin.cron:
+ name: nginx-logrotate
+ hour: "0"
+ minute: "0"
+ job: /usr/local/bin/nginx-logrotate
+ when: ansible_system == "OpenBSD"
+
- name: Enable nginx service
ansible.builtin.service:
name: nginx
diff --git a/roles/nginx/server/templates/nginx-logrotate.sh b/roles/nginx/templates/nginx-logrotate.sh
similarity index 100%
rename from roles/nginx/server/templates/nginx-logrotate.sh
rename to roles/nginx/templates/nginx-logrotate.sh
diff --git a/roles/nginx/server/templates/nginx.conf.j2 b/roles/nginx/templates/nginx.conf.j2
similarity index 76%
rename from roles/nginx/server/templates/nginx.conf.j2
rename to roles/nginx/templates/nginx.conf.j2
index 1bc0e2b..b6733d2 100644
--- a/roles/nginx/server/templates/nginx.conf.j2
+++ b/roles/nginx/templates/nginx.conf.j2
@@ -8,7 +8,10 @@ events {
}
http {
- access_log {{ nginx_logdir }}/access.log combined;
+ log_format custom '$remote_addr - $remote_user [$time_local] '
+ '"$request" $status $body_bytes_sent '
+ '"$http_referer" "$http_user_agent" ($request_time)';
+ access_log {{ nginx_logdir }}/access.log custom;
proxy_ssl_certificate {{ tls_certs }}/{{ inventory_hostname }}.crt;
proxy_ssl_certificate_key {{ tls_private }}/{{ inventory_hostname }}.key;
@@ -23,16 +26,19 @@ http {
}
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
-{% if plaintext is defined %}
+{% if nginx_plaintext is defined %}
server {
listen 80;
listen [::]:80;
server_name {{ inventory_hostname }};
location /.well-known/acme-challenge/ {
- proxy_pass https://certbot.home.foo.sh/.well-known/acme-challenge/;
+ proxy_pass http://certbot.home.foo.sh/.well-known/acme-challenge/;
}
location / {
return 301 https://$host$request_uri;
@@ -60,6 +66,10 @@ http {
root /srv/web/{{ inventory_hostname }};
+ location = /stub_status {
+ stub_status;
+ }
+
include /etc/nginx/conf.d/{{ inventory_hostname }}/*.conf;
}
diff --git a/roles/nginx/server/vars/OpenBSD.yml b/roles/nginx/vars/OpenBSD.yml
similarity index 100%
rename from roles/nginx/server/vars/OpenBSD.yml
rename to roles/nginx/vars/OpenBSD.yml
diff --git a/roles/nginx/server/vars/RedHat.yml b/roles/nginx/vars/RedHat.yml
similarity index 100%
rename from roles/nginx/server/vars/RedHat.yml
rename to roles/nginx/vars/RedHat.yml
diff --git a/roles/nginx_exporter/defaults/main.yml b/roles/nginx_exporter/defaults/main.yml
new file mode 100644
index 0000000..6f214a3
--- /dev/null
+++ b/roles/nginx_exporter/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+nginx_exporter_pkg: >-
+ nginx-prometheus-exporter_{{ nginx_exporter_version }}_linux_amd64
diff --git a/roles/nginx_exporter/handlers/main.yml b/roles/nginx_exporter/handlers/main.yml
new file mode 100644
index 0000000..690f1c7
--- /dev/null
+++ b/roles/nginx_exporter/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart nginx_exporter
+ ansible.builtin.systemd:
+ name: nginx_exporter
+ daemon_reload: true
+ state: restarted
diff --git a/roles/nginx_exporter/tasks/main.yml b/roles/nginx_exporter/tasks/main.yml
new file mode 100644
index 0000000..8d445ed
--- /dev/null
+++ b/roles/nginx_exporter/tasks/main.yml
@@ -0,0 +1,88 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: nginx_exporter
+ system: true
+
+- name: Create user
+ ansible.builtin.user:
+ name: nginx_exporter
+ comment: Prometheus NGINX Exporter
+ group: nginx_exporter
+ groups: hostkey
+ create_home: false
+ home: /var/empty
+ shell: /sbin/nologin
+ system: true
+
+- name: Download package
+ ansible.builtin.get_url:
+ url: >-
+ {{
+ "https://github.com/nginxinc/nginx-prometheus-exporter/releases/"
+ + "download/v" + nginx_exporter_version + "/" + nginx_exporter_pkg
+ + ".tar.gz"
+ }}
+ dest: "/usr/local/src/{{ nginx_exporter_pkg }}.tar.gz"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create directory for extracing package
+ ansible.builtin.file:
+ path: "/usr/local/src/{{ nginx_exporter_pkg }}"
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Extract nginx_exporter
+ ansible.builtin.unarchive:
+ src: "/usr/local/src/{{ nginx_exporter_pkg }}.tar.gz"
+ dest: "/usr/local/src/{{ nginx_exporter_pkg }}"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ creates: "/usr/local/src/{{ nginx_exporter_pkg }}/nginx-prometheus-exporter"
+ remote_src: true
+
+- name: Copy binary
+ ansible.builtin.copy:
+ dest: "/usr/local/bin/nginx_exporter"
+ src: "/usr/local/src/{{ nginx_exporter_pkg }}/nginx-prometheus-exporter"
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ remote_src: true
+ notify: Restart nginx_exporter
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/nginx_exporter
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create web-config
+ ansible.builtin.template:
+ dest: /etc/nginx_exporter/web-config.yml
+ src: web-config.yml.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx_exporter
+
+- name: Create service file
+ ansible.builtin.template:
+ dest: /etc/systemd/system/nginx_exporter.service
+ src: nginx_exporter.service.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx_exporter
+
+- name: Enable service
+ ansible.builtin.service:
+ name: nginx_exporter
+ state: started
+ enabled: true
diff --git a/roles/nginx_exporter/templates/nginx_exporter.service.j2 b/roles/nginx_exporter/templates/nginx_exporter.service.j2
new file mode 100644
index 0000000..bf1eb12
--- /dev/null
+++ b/roles/nginx_exporter/templates/nginx_exporter.service.j2
@@ -0,0 +1,21 @@
+[Unit]
+Description=Prometheus NGINX Exporter
+After=syslog.target
+After=network.target
+
+[Service]
+Type=simple
+User=nginx_exporter
+Group=nginx_exporter
+ExecStart=/usr/local/bin/nginx_exporter \
+ --web.config.file=/etc/nginx_exporter/web-config.yml \
+{% for host in groups['proxy'] %}
+ --nginx.scrape-uri=https://{{ host }}/stub_status \
+{% endfor %}
+ --nginx.ssl-ca-cert={{ tls_certs }}/ca.crt \
+ --nginx.ssl-client-cert={{ tls_certs }}/{{ inventory_hostname }}.crt \
+ --nginx.ssl-client-key={{ tls_private }}/{{ inventory_hostname }}.key
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/nginx_exporter/templates/web-config.yml.j2 b/roles/nginx_exporter/templates/web-config.yml.j2
new file mode 100644
index 0000000..03e5466
--- /dev/null
+++ b/roles/nginx_exporter/templates/web-config.yml.j2
@@ -0,0 +1,11 @@
+---
+tls_server_config:
+ key_file: {{ tls_private }}/{{ inventory_hostname }}.key
+ cert_file: {{ tls_certs }}/{{ inventory_hostname }}.crt
+ client_ca_file: {{ tls_certs }}/ca.crt
+ client_auth_type: RequireAndVerifyClientCert
+ client_allowed_sans:
+{% for host in groups['prometheus'] %}
+ - {{ host }}
+{% endfor %}
+ min_version: TLS13
diff --git a/roles/nginx_logsync/tasks/main.yml b/roles/nginx_logsync/tasks/main.yml
new file mode 100644
index 0000000..0d7c9ff
--- /dev/null
+++ b/roles/nginx_logsync/tasks/main.yml
@@ -0,0 +1,34 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: logsync
+ system: true
+
+- name: Create user
+ ansible.builtin.user:
+ name: logsync
+ comment: Service logsync
+ create_home: false
+ group: logsync
+ home: /var/empty
+ shell: /sbin/nologin
+
+- name: Create authorized_keys
+ ansible.builtin.copy:
+ dest: /etc/ssh/authorized_keys.logsync
+ src: ../files/ssh/logsync.pub
+ mode: "0640"
+ owner: root
+ group: logsync
+
+- name: Configure sshd chroot
+ ansible.builtin.blockinfile:
+ path: /etc/ssh/sshd_config
+ block: |
+ Match User logsync
+ ChrootDirectory /var/www/logs
+ ForceCommand internal-sftp
+ AuthorizedKeysFile /etc/ssh/authorized_keys.logsync
+ marker: "# {mark} ANSIBLE MANAGED BLOCK (user logsync)"
+ validate: "sshd -t -f %s"
+ notify: Restart sshd
diff --git a/roles/nginx_site/defaults/main.yml b/roles/nginx_site/defaults/main.yml
new file mode 100644
index 0000000..2296dbc
--- /dev/null
+++ b/roles/nginx_site/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+nginx_site_plaintext: true
diff --git a/roles/nginx_site/tasks/main.yml b/roles/nginx_site/tasks/main.yml
new file mode 100644
index 0000000..0afcf5e
--- /dev/null
+++ b/roles/nginx_site/tasks/main.yml
@@ -0,0 +1,47 @@
+---
+- name: "Create site data directory for {{ nginx_site_name }}"
+ ansible.builtin.file:
+ path: "/srv/web/{{ nginx_site_name }}"
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ when: nginx_site_redirect is not defined and nginx_site_proxy is not defined
+
+- name: "Create site config for {{ nginx_site_name }}"
+ ansible.builtin.template:
+ dest: /etc/nginx/conf.d/{{ nginx_site_name }}.conf
+ src: site.conf.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
+
+- name: "Copy site private key for {{ nginx_site_name }}"
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/{{ nginx_site_name }}.key"
+ src: "{{ item }}"
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ with_first_found:
+ - "/srv/letsencrypt/live/{{ nginx_site_name }}/privkey.pem"
+ - "/srv/ca/private/{{ nginx_site_name }}.key"
+ - "/srv/ca/private/{{ inventory_hostname }}.key"
+ tags: certificates
+ notify: Restart nginx
+
+- name: "Copy site certificate for {{ nginx_site_name }}"
+ ansible.builtin.copy:
+ src: "{{ item }}"
+ dest: "{{ tls_certs }}/{{ nginx_site_name }}-fullchain.crt"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ validate: /usr/bin/openssl x509 -in %s -noout
+ with_first_found:
+ - "/srv/letsencrypt/live/{{ nginx_site_name }}/fullchain.pem"
+ - "/srv/ca/certs/hosts/{{ nginx_site_name }}.crt"
+ - "/srv/ca/certs/hosts/{{ inventory_hostname }}.crt"
+ tags: certificates
+ notify: Restart nginx
diff --git a/roles/nginx_site/templates/audiobooks.foo.sh.conf.j2 b/roles/nginx_site/templates/audiobooks.foo.sh.conf.j2
new file mode 100644
index 0000000..e838c5f
--- /dev/null
+++ b/roles/nginx_site/templates/audiobooks.foo.sh.conf.j2
@@ -0,0 +1,3 @@
+ # this should be changed to only affect uploads
+ client_max_body_size 10g;
+
diff --git a/roles/nginx_site/templates/collab.foo.sh.conf.j2 b/roles/nginx_site/templates/collab.foo.sh.conf.j2
new file mode 100644
index 0000000..93e1c8b
--- /dev/null
+++ b/roles/nginx_site/templates/collab.foo.sh.conf.j2
@@ -0,0 +1,6 @@
+ client_max_body_size 50m;
+
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'";
+ add_header Referrer-Policy "no-referrer";
+ add_header X-Content-Type-Options "nosniff";
+ add_header X-XSS-Protection "1; mode=block";
diff --git a/roles/nginx_site/templates/git.foo.sh.conf.j2 b/roles/nginx_site/templates/git.foo.sh.conf.j2
new file mode 100644
index 0000000..4bfc067
--- /dev/null
+++ b/roles/nginx_site/templates/git.foo.sh.conf.j2
@@ -0,0 +1,2 @@
+ # disable any limits to avoid HTTP 413 for large pushes
+ client_max_body_size 100m;
diff --git a/roles/nginx/site/templates/gw.home.foo.sh.conf.j2 b/roles/nginx_site/templates/gw.home.foo.sh.conf.j2
similarity index 100%
rename from roles/nginx/site/templates/gw.home.foo.sh.conf.j2
rename to roles/nginx_site/templates/gw.home.foo.sh.conf.j2
diff --git a/roles/nginx_site/templates/movies.foo.sh.conf.j2 b/roles/nginx_site/templates/movies.foo.sh.conf.j2
new file mode 100644
index 0000000..760e07b
--- /dev/null
+++ b/roles/nginx_site/templates/movies.foo.sh.conf.j2
@@ -0,0 +1,5 @@
+ add_header Content-Security-Policy "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com";
+ add_header Referrer-Policy "no-referrer";
+ add_header X-Content-Type-Options "nosniff";
+ add_header X-XSS-Protection "1; mode=block";
+
diff --git a/roles/nginx/site/templates/registry.foo.sh.conf.j2 b/roles/nginx_site/templates/registry.foo.sh.conf.j2
similarity index 100%
rename from roles/nginx/site/templates/registry.foo.sh.conf.j2
rename to roles/nginx_site/templates/registry.foo.sh.conf.j2
diff --git a/roles/nginx_site/templates/site.conf.j2 b/roles/nginx_site/templates/site.conf.j2
new file mode 100644
index 0000000..ca54573
--- /dev/null
+++ b/roles/nginx_site/templates/site.conf.j2
@@ -0,0 +1,68 @@
+{% if nginx_site_proxy is defined and nginx_site_proxy is not string %}
+upstream {{ nginx_site_name }} {
+{% if nginx_site_load_balance_method is defined %}
+ {{ nginx_site_load_balance_method }};
+{% endif %}
+{% for item in nginx_site_proxy %}
+{% set item = item | regex_replace("^(https://)?([^/]*).*$", "\\2") %}
+{% if item | regex_search(".*:[0-9]+$") %}
+ server {{ item }};
+{% else %}
+ server {{ item }}:443;
+{% endif %}
+{% endfor %}
+}
+{% endif %}
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name {{ nginx_site_name }};
+
+ access_log {{ nginx_logdir }}/{{ nginx_site_name }}.access.log custom;
+ error_log {{ nginx_logdir }}/{{ nginx_site_name }}.error.log warn;
+
+ add_header Strict-Transport-Security "max-age=63072000" always;
+
+ ssl_certificate {{ tls_certs }}/{{ nginx_site_name }}-fullchain.crt;
+ ssl_certificate_key {{ tls_private }}/{{ nginx_site_name }}.key;
+
+{% include "./{}.conf.j2".format(nginx_site_name) ignore missing %}
+{% if nginx_site_redirect is defined %}
+ return 301 {{ nginx_site_redirect }};
+{% elif nginx_site_proxy is defined %}
+ location / {
+{% if nginx_site_proxy is not string %}
+{% set path = nginx_site_proxy[0] | regex_replace("^(https://)?([^/]*)(.*)$", "\\3") %}
+ # https://trac.nginx.org/nginx/ticket/1307
+ proxy_ssl_verify off;
+ proxy_pass https://{{ nginx_site_name }}{{ path }};
+{% else %}
+ proxy_pass {{ nginx_site_proxy }};
+{% endif %}
+ }
+{% else %}
+ root /srv/web/{{ nginx_site_name }};
+{% endif %}
+}
+{% if nginx_site_plaintext %}
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name {{ nginx_site_name }};
+{% if nginx_site_name == 'certbot.home.foo.sh' and 'proxy' not in groups %}
+ root /srv/web/{{ nginx_site_name }};
+{% else %}
+ location /.well-known/acme-challenge/ {
+ proxy_pass https://certbot.home.foo.sh/.well-known/acme-challenge/;
+ }
+ location / {
+{% if nginx_site_redirect is defined %}
+ return 301 {{ nginx_site_redirect }};
+{% else %}
+ return 301 https://$host$request_uri;
+{% endif %}
+ }
+{% endif %}
+}
+{% endif %}
diff --git a/roles/nginx/site/templates/www.foo.sh.conf.j2 b/roles/nginx_site/templates/www.foo.sh.conf.j2
similarity index 100%
rename from roles/nginx/site/templates/www.foo.sh.conf.j2
rename to roles/nginx_site/templates/www.foo.sh.conf.j2
diff --git a/roles/node_exporter/files/md_info.sh b/roles/node_exporter/files/md_info.sh
new file mode 100755
index 0000000..bf72d1b
--- /dev/null
+++ b/roles/node_exporter/files/md_info.sh
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+
+set -eu
+
+for MD_DEVICE in /dev/md/*; do
+ if [ -b "$MD_DEVICE" ]; then
+ # Subshell to avoid eval'd variables from leaking between iterations
+ (
+ # Resolve symlink to discover device, e.g. /dev/md127
+ MD_DEVICE_NUM=$(readlink -f "${MD_DEVICE}")
+
+ # Remove /dev/ prefix
+ MD_DEVICE_NUM=${MD_DEVICE_NUM#/dev/}
+ MD_DEVICE=${MD_DEVICE#/dev/md/}
+
+ # Query sysfs for info about md device
+ SYSFS_BASE="/sys/devices/virtual/block/${MD_DEVICE_NUM}/md"
+ MD_LAYOUT=$(cat "${SYSFS_BASE}/layout")
+ MD_LEVEL=$(cat "${SYSFS_BASE}/level")
+ MD_METADATA_VERSION=$(cat "${SYSFS_BASE}/metadata_version")
+ MD_NUM_RAID_DISKS=$(cat "${SYSFS_BASE}/raid_disks")
+
+ # Remove 'raid' prefix from RAID level
+ MD_LEVEL=${MD_LEVEL#raid}
+
+ # Output disk metrics
+ for RAID_DISK in "${SYSFS_BASE}"/rd[0-9]*; do
+ DISK=$(readlink -f "${RAID_DISK}/block")
+ DISK_DEVICE=$(basename "${DISK}")
+ RAID_DISK_DEVICE=$(basename "${RAID_DISK}")
+ RAID_DISK_INDEX=${RAID_DISK_DEVICE#rd}
+ RAID_DISK_STATE=$(cat "${RAID_DISK}/state")
+
+ DISK_SET=""
+ # Determine disk set using logic from mdadm: https://github.com/neilbrown/mdadm/commit/2c096ebe4b
+ if [[ ${RAID_DISK_STATE} == "in_sync" && ${MD_LEVEL} == 10 && $((MD_LAYOUT & ~0x1ffff)) ]]; then
+ NEAR_COPIES=$((MD_LAYOUT & 0xff))
+ FAR_COPIES=$(((MD_LAYOUT >> 8) & 0xff))
+ COPIES=$((NEAR_COPIES * FAR_COPIES))
+
+ if [[ $((MD_NUM_RAID_DISKS % COPIES == 0)) && $((COPIES <= 26)) ]]; then
+ DISK_SET=$((RAID_DISK_INDEX % COPIES))
+ fi
+ fi
+
+ echo -n "node_md_disk_info{disk_device=\"${DISK_DEVICE}\", md_device=\"${MD_DEVICE_NUM}\""
+ if [[ -n ${DISK_SET} ]]; then
+ SET_LETTERS=({A..Z})
+ echo -n ", md_set=\"${SET_LETTERS[${DISK_SET}]}\""
+ fi
+ echo "} 1"
+ done
+
+ # Output RAID array metrics
+ # NOTE: Metadata version is a label rather than a separate metric because the version can be a string
+ echo "node_md_info{md_device=\"${MD_DEVICE_NUM}\", md_name=\"${MD_DEVICE}\", raid_level=\"${MD_LEVEL}\", md_metadata_version=\"${MD_METADATA_VERSION}\"} 1"
+ )
+ fi
+done
diff --git a/roles/node_exporter/files/node-exporter-run-textfile-collector.sh b/roles/node_exporter/files/node-exporter-run-textfile-collector.sh
new file mode 100755
index 0000000..97dd14c
--- /dev/null
+++ b/roles/node_exporter/files/node-exporter-run-textfile-collector.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+set -eu
+
+umask 022
+
+PATH="/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin"
+
+if [ "${1:-}" = "-v" ]; then
+ shift
+ VERBOSE=true
+else
+ VERBOSE=false
+fi
+
+if [ -n "${1:-}" ]; then
+ echo "Usage: $(basename "$0") [-v]" 1>&2
+ exit 1
+fi
+
+if [ "$(uname -s)" = "OpenBSD" ]; then
+ OUTDIR="/var/db/node-exporter"
+else
+ OUTDIR="/var/lib/prometheus/node-exporter"
+fi
+"$VERBOSE" && echo "Using output directory '${OUTDIR}'"
+
+for script in /usr/local/libexec/node-exporter/*; do
+ [ -x "$script" ] || continue
+ "$VERBOSE" && echo "Processing script '${script}'"
+ target="${OUTDIR}/$(basename "$script")"
+ tmpfile="$(mktemp -p "$OUTDIR")"
+ if "$script" > "$tmpfile" ; then
+ "$VERBOSE" && echo " Success, updating stats"
+ mv "$tmpfile" "$target"
+ else
+ "$VERBOSE" && echo " Failure, skipping stats update"
+ rm -f "$tmpfile"
+ fi
+done
diff --git a/roles/node_exporter/files/smartmon.sh b/roles/node_exporter/files/smartmon.sh
new file mode 100755
index 0000000..4cefec5
--- /dev/null
+++ b/roles/node_exporter/files/smartmon.sh
@@ -0,0 +1,204 @@
+#!/usr/bin/env bash
+#
+# Script informed by the collectd monitoring script for smartmontools (using smartctl)
+# by Samuel B. (c) 2012
+# source at: http://devel.dob.sk/collectd-scripts/
+
+# TODO: This probably needs to be a little more complex. The raw numbers can have more
+# data in them than you'd think.
+# http://arstechnica.com/civis/viewtopic.php?p=22062211
+
+# Formatting done via shfmt -i 2
+# https://github.com/mvdan/sh
+
+# Ensure predictable numeric / date formats, etc.
+export LC_ALL=C
+
+parse_smartctl_attributes_awk="$(
+ cat <<'SMARTCTLAWK'
+$1 ~ /^ *[0-9]+$/ && $2 ~ /^[a-zA-Z0-9_-]+$/ {
+ gsub(/-/, "_");
+ printf "%s_value{%s,smart_id=\"%s\"} %d\n", $2, labels, $1, $4
+ printf "%s_worst{%s,smart_id=\"%s\"} %d\n", $2, labels, $1, $5
+ printf "%s_threshold{%s,smart_id=\"%s\"} %d\n", $2, labels, $1, $6
+ printf "%s_raw_value{%s,smart_id=\"%s\"} %e\n", $2, labels, $1, $10
+}
+SMARTCTLAWK
+)"
+
+smartmon_attrs="$(
+ cat <<'SMARTMONATTRS'
+airflow_temperature_cel
+command_timeout
+current_pending_sector
+end_to_end_error
+erase_fail_count
+g_sense_error_rate
+hardware_ecc_recovered
+host_reads_32mib
+host_reads_mib
+host_writes_32mib
+host_writes_mib
+load_cycle_count
+media_wearout_indicator
+nand_writes_1gib
+offline_uncorrectable
+power_cycle_count
+power_on_hours
+program_fail_cnt_total
+program_fail_count
+raw_read_error_rate
+reallocated_event_count
+reallocated_sector_ct
+reported_uncorrect
+runtime_bad_block
+sata_downshift_count
+seek_error_rate
+spin_retry_count
+spin_up_time
+start_stop_count
+temperature_case
+temperature_celsius
+temperature_internal
+total_lbas_read
+total_lbas_written
+udma_crc_error_count
+unsafe_shutdown_count
+unused_rsvd_blk_cnt_tot
+wear_leveling_count
+workld_host_reads_perc
+workld_media_wear_indic
+workload_minutes
+SMARTMONATTRS
+)"
+smartmon_attrs="$(echo "${smartmon_attrs}" | xargs | tr ' ' '|')"
+
+parse_smartctl_attributes() {
+ local disk="$1"
+ local disk_type="$2"
+ local labels="disk=\"${disk}\",type=\"${disk_type}\""
+ sed 's/^ \+//g' |
+ awk -v labels="${labels}" "${parse_smartctl_attributes_awk}" 2>/dev/null |
+ tr '[:upper:]' '[:lower:]' |
+ grep -E "(${smartmon_attrs})"
+}
+
+parse_smartctl_scsi_attributes() {
+ local disk="$1"
+ local disk_type="$2"
+ local labels="disk=\"${disk}\",type=\"${disk_type}\""
+ while read -r line; do
+ attr_type="$(echo "${line}" | tr '=' ':' | cut -f1 -d: | sed 's/^ \+//g' | tr ' ' '_')"
+ attr_value="$(echo "${line}" | tr '=' ':' | cut -f2 -d: | sed 's/^ \+//g')"
+ case "${attr_type}" in
+ number_of_hours_powered_up_) power_on="$(echo "${attr_value}" | awk '{ printf "%e\n", $1 }')" ;;
+ Current_Drive_Temperature) temp_cel="$(echo "${attr_value}" | cut -f1 -d' ' | awk '{ printf "%e\n", $1 }')" ;;
+ Blocks_sent_to_initiator_) lbas_read="$(echo "${attr_value}" | awk '{ printf "%e\n", $1 }')" ;;
+ Blocks_received_from_initiator_) lbas_written="$(echo "${attr_value}" | awk '{ printf "%e\n", $1 }')" ;;
+ Accumulated_start-stop_cycles) power_cycle="$(echo "${attr_value}" | awk '{ printf "%e\n", $1 }')" ;;
+ Elements_in_grown_defect_list) grown_defects="$(echo "${attr_value}" | awk '{ printf "%e\n", $1 }')" ;;
+ esac
+ done
+ [ -n "$power_on" ] && echo "power_on_hours_raw_value{${labels},smart_id=\"9\"} ${power_on}"
+ [ -n "$temp_cel" ] && echo "temperature_celsius_raw_value{${labels},smart_id=\"194\"} ${temp_cel}"
+ [ -n "$lbas_read" ] && echo "total_lbas_read_raw_value{${labels},smart_id=\"242\"} ${lbas_read}"
+ [ -n "$lbas_written" ] && echo "total_lbas_written_raw_value{${labels},smart_id=\"241\"} ${lbas_written}"
+ [ -n "$power_cycle" ] && echo "power_cycle_count_raw_value{${labels},smart_id=\"12\"} ${power_cycle}"
+ [ -n "$grown_defects" ] && echo "grown_defects_count_raw_value{${labels},smart_id=\"-1\"} ${grown_defects}"
+}
+
+parse_smartctl_info() {
+ local -i smart_available=0 smart_enabled=0 smart_healthy=
+ local disk="$1" disk_type="$2"
+ local model_family='' device_model='' serial_number='' fw_version='' vendor='' product='' revision='' lun_id=''
+ while read -r line; do
+ info_type="$(echo "${line}" | cut -f1 -d: | tr ' ' '_')"
+ info_value="$(echo "${line}" | cut -f2- -d: | sed 's/^ \+//g' | sed 's/"/\\"/')"
+ case "${info_type}" in
+ Model_Family) model_family="${info_value}" ;;
+ Device_Model|Model_Number) device_model="${info_value}" ;;
+ Serial_Number|Serial_number) serial_number="${info_value}" ;;
+ Firmware_Version) fw_version="${info_value}" ;;
+ Vendor) vendor="${info_value}" ;;
+ Product) product="${info_value}" ;;
+ Revision) revision="${info_value}" ;;
+ Logical_Unit_id) lun_id="${info_value}" ;;
+ esac
+ if [[ "${info_type}" == 'SMART_support_is' ]]; then
+ case "${info_value:0:7}" in
+ Enabled) smart_available=1; smart_enabled=1 ;;
+ Availab) smart_available=1; smart_enabled=0 ;;
+ Unavail) smart_available=0; smart_enabled=0 ;;
+ esac
+ fi
+ if [[ "${info_type}" == 'SMART_overall-health_self-assessment_test_result' ]]; then
+ case "${info_value:0:6}" in
+ PASSED) smart_healthy=1 ;;
+ *) smart_healthy=0 ;;
+ esac
+ elif [[ "${info_type}" == 'SMART_Health_Status' ]]; then
+ case "${info_value:0:2}" in
+ OK) smart_healthy=1 ;;
+ *) smart_healthy=0 ;;
+ esac
+ fi
+ done
+ echo "device_info{disk=\"${disk}\",type=\"${disk_type}\",vendor=\"${vendor}\",product=\"${product}\",revision=\"${revision}\",lun_id=\"${lun_id}\",model_family=\"${model_family}\",device_model=\"${device_model}\",serial_number=\"${serial_number}\",firmware_version=\"${fw_version}\"} 1"
+ echo "device_smart_available{disk=\"${disk}\",type=\"${disk_type}\"} ${smart_available}"
+ echo "device_smart_enabled{disk=\"${disk}\",type=\"${disk_type}\"} ${smart_enabled}"
+ [[ "${smart_healthy}" != "" ]] && echo "device_smart_healthy{disk=\"${disk}\",type=\"${disk_type}\"} ${smart_healthy}"
+}
+
+output_format_awk="$(
+ cat <<'OUTPUTAWK'
+BEGIN { v = "" }
+v != $1 {
+ print "# HELP smartmon_" $1 " SMART metric " $1;
+ print "# TYPE smartmon_" $1 " gauge";
+ v = $1
+}
+{print "smartmon_" $0}
+OUTPUTAWK
+)"
+
+format_output() {
+ sort |
+ awk -F'{' "${output_format_awk}"
+}
+
+smartctl_version="$(/usr/sbin/smartctl -V | head -n1 | awk '$1 == "smartctl" {print $2}')"
+
+echo "smartctl_version{version=\"${smartctl_version}\"} 1" | format_output
+
+if [[ "$(expr "${smartctl_version}" : '\([0-9]*\)\..*')" -lt 6 ]]; then
+ exit
+fi
+
+device_list="$(/usr/sbin/smartctl --scan-open | awk '/^\/dev/{print $1 "|" $3}')"
+
+for device in ${device_list}; do
+ disk="$(echo "${device}" | cut -f1 -d'|')"
+ type="$(echo "${device}" | cut -f2 -d'|')"
+ active=1
+ echo "smartctl_run{disk=\"${disk}\",type=\"${type}\"}" "$(TZ=UTC date '+%s')"
+ # Check if the device is in a low-power mode
+ /usr/sbin/smartctl -n standby -d "${type}" "${disk}" > /dev/null || active=0
+ echo "device_active{disk=\"${disk}\",type=\"${type}\"}" "${active}"
+ # Skip further metrics to prevent the disk from spinning up
+ test ${active} -eq 0 && continue
+ # Get the SMART information and health
+ /usr/sbin/smartctl -i -H -d "${type}" "${disk}" | parse_smartctl_info "${disk}" "${type}"
+ # Get the SMART attributes
+ case ${type} in
+ sat) /usr/sbin/smartctl -A -d "${type}" "${disk}" | parse_smartctl_attributes "${disk}" "${type}" ;;
+ sat+megaraid*) /usr/sbin/smartctl -A -d "${type}" "${disk}" | parse_smartctl_attributes "${disk}" "${type}" ;;
+ scsi) /usr/sbin/smartctl -A -d "${type}" "${disk}" | parse_smartctl_scsi_attributes "${disk}" "${type}" ;;
+ megaraid*) /usr/sbin/smartctl -A -d "${type}" "${disk}" | parse_smartctl_scsi_attributes "${disk}" "${type}" ;;
+ nvme*) /usr/sbin/smartctl -A -d "${type}" "${disk}" | parse_smartctl_scsi_attributes "${disk}" "${type}" ;;
+ usbprolific) /usr/sbin/smartctl -A -d "${type}" "${disk}" | parse_smartctl_attributes "${disk}" "${type}" ;;
+ *)
+ (>&2 echo "disk type is not sat, scsi, nvme or megaraid but ${type}")
+ exit
+ ;;
+ esac
+done | format_output
diff --git a/roles/node_exporter/handlers/main.yml b/roles/node_exporter/handlers/main.yml
new file mode 100644
index 0000000..5bfbd16
--- /dev/null
+++ b/roles/node_exporter/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Restart node_exporter
+ ansible.builtin.service:
+ name: >-
+ {% if ansible_distribution == "OpenBSD" -%}
+ {{ "node_exporter" -}}
+ {% else -%}
+ {{ "prometheus-node-exporter" -}}
+ {% endif -%}
+ state: restarted
diff --git a/roles/node_exporter/meta/main.yml b/roles/node_exporter/meta/main.yml
new file mode 100644
index 0000000..ed212b9
--- /dev/null
+++ b/roles/node_exporter/meta/main.yml
@@ -0,0 +1,6 @@
+---
+dependencies:
+ - role: epel_repo
+ when:
+ - ansible_os_family == "RedHat"
+ - ansible_distribution != "Fedora"
diff --git a/roles/node_exporter/tasks/main.yml b/roles/node_exporter/tasks/main.yml
new file mode 100644
index 0000000..f1c0968
--- /dev/null
+++ b/roles/node_exporter/tasks/main.yml
@@ -0,0 +1,132 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: >-
+ {% if ansible_distribution in ["Fedora", "OpenBSD"] -%}
+ {{ "node_exporter" -}}
+ {% else -%}
+ {{ "golang-github-prometheus-node-exporter" -}}
+ {% endif -%}
+ state: installed
+
+- name: Allow prometheus user to read private key
+ ansible.builtin.user:
+ name: >-
+ {% if ansible_distribution == "OpenBSD" -%}
+ {{ "_nodeexporter" -}}
+ {% else -%}
+ {{ "prometheus" -}}
+ {% endif -%}
+ groups: hostkey
+ append: true
+ create_home: false
+ notify: Restart node_exporter
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/node_exporter
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create web-config
+ ansible.builtin.template:
+ dest: /etc/node_exporter/web-config.yml
+ src: web-config.yml.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart node_exporter
+
+- name: Create textfile collector directory
+ ansible.builtin.file:
+ path: /var/db/node-exporter
+ state: directory
+ mode: 0755
+ owner: _nodeexporter
+ group: _nodeexporter
+ when: ansible_os_family == "OpenBSD"
+
+- name: Create directory for textfile collector scripts
+ ansible.builtin.file:
+ path: /usr/local/libexec/node-exporter
+ state: directory
+ mode: 0755
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Add script for running textfile collector scripts
+ ansible.builtin.copy:
+ dest: /usr/local/sbin/node-exporter-run-textfile-collector
+ src: node-exporter-run-textfile-collector.sh
+ mode: 0755
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Add cron job for running textfile collector scripts
+ ansible.builtin.cron:
+ name: node-exporter-run-textfile-collector
+ job: /usr/local/sbin/node-exporter-run-textfile-collector
+ minute: "*/10"
+
+- name: Modify config (pre 1.5.0)
+ ansible.builtin.lineinfile:
+ path: /etc/default/prometheus-node-exporter
+ regexp: "^ARGS="
+ line: >-
+ ARGS="--collector.filesystem.ignored-mount-points='^/(dev|proc|sys|run/(user|credentials/systemd-.+))($|/)'
+ --collector.netclass.ignored-devices='^(br-|docker|veth).+$'
+ --collector.netdev.device-exclude='^(br-|docker|veth).+$'
+ --web.config=/etc/node_exporter/web-config.yml
+ --collector.textfile.directory=/var/lib/prometheus/node-exporter"
+ notify: Restart node_exporter
+ when:
+ - ansible_os_family == "RedHat"
+ - ansible_distribution != "Fedora"
+
+- name: Modify config
+ ansible.builtin.lineinfile:
+ path: /etc/default/prometheus-node-exporter
+ regexp: "^ARGS="
+ line: >-
+ ARGS="--collector.filesystem.ignored-mount-points='^/(dev|proc|sys|run/(user|credentials/systemd-.+))($|/)'
+ --collector.netclass.ignored-devices='^(br-|docker|veth).+$'
+ --collector.netdev.device-exclude='^(br-|docker|veth).+$'
+ --web.config.file=/etc/node_exporter/web-config.yml
+ --collector.textfile.directory=/var/lib/prometheus/node-exporter"
+ notify: Restart node_exporter
+ when:
+ - ansible_distribution == "Fedora"
+
+- name: Install disk and raid monitoring scripts
+ ansible.builtin.copy:
+ dest: "/usr/local/libexec/node-exporter/{{ item }}"
+ src: "{{ item }}"
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ with_items:
+ - md_info.sh
+ - smartmon.sh
+ when:
+ - ansible_virtualization_role == "host"
+ - ansible_os_family == "RedHat"
+
+- name: Enable service
+ ansible.builtin.service:
+ name: node_exporter
+ state: started
+ enabled: true
+ arguments: >-
+ --web.config.file=/etc/node_exporter/web-config.yml
+ --collector.textfile.directory=/var/db/node-exporter
+ notify: Restart node_exporter
+ when: ansible_os_family == "OpenBSD"
+
+- name: Enable service
+ ansible.builtin.service:
+ name: prometheus-node-exporter
+ state: started
+ enabled: true
+ when: ansible_os_family == "RedHat"
diff --git a/roles/node_exporter/templates/web-config.yml.j2 b/roles/node_exporter/templates/web-config.yml.j2
new file mode 100644
index 0000000..07cdaf3
--- /dev/null
+++ b/roles/node_exporter/templates/web-config.yml.j2
@@ -0,0 +1,7 @@
+---
+tls_server_config:
+ key_file: {{ tls_private }}/{{ inventory_hostname }}.key
+ cert_file: {{ tls_certs }}/{{ inventory_hostname }}.crt
+ client_ca_file: {{ tls_certs }}/ca.crt
+ client_auth_type: RequireAndVerifyClientCert
+ min_version: TLS13
diff --git a/roles/nodered/defaults/main.yml b/roles/nodered/defaults/main.yml
new file mode 100644
index 0000000..bf68f6d
--- /dev/null
+++ b/roles/nodered/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+nodered_version: latest
diff --git a/roles/nodered/handlers/main.yml b/roles/nodered/handlers/main.yml
new file mode 100644
index 0000000..073db56
--- /dev/null
+++ b/roles/nodered/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart nodered
+ ansible.builtin.systemd_service:
+ name: nodered-container
+ state: restarted
+ daemon_reload: true
diff --git a/roles/nodered/meta/main.yml b/roles/nodered/meta/main.yml
new file mode 100644
index 0000000..305b1b2
--- /dev/null
+++ b/roles/nodered/meta/main.yml
@@ -0,0 +1,4 @@
+---
+dependencies:
+ - {role: nginx}
+ - {role: podman}
diff --git a/roles/nodered/tasks/main.yml b/roles/nodered/tasks/main.yml
new file mode 100644
index 0000000..011e6f3
--- /dev/null
+++ b/roles/nodered/tasks/main.yml
@@ -0,0 +1,80 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: nodered
+
+- name: Create user
+ ansible.builtin.user:
+ name: nodered
+ comment: Podman NodeRed
+ group: nodered
+ shell: /sbin/nologin
+
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - nodered
+ creates: /var/lib/systemd/linger/nodered
+
+- name: Fix SELinux contexts from config directory
+ community.general.sefcontext:
+ path: /export/nodered(/.*)?
+ setype: container_file_t
+ when: ansible_selinux_python_present
+
+- name: Get subgid number
+ ansible.builtin.command:
+ argv:
+ - awk
+ - "-F:"
+ - '{ if ($1 == "nodered") print $2 + 999 }'
+ - /etc/subgid
+ changed_when: false
+ register: subgid
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /export/nodered
+ state: directory
+ mode: "0770"
+ owner: root
+ group: "{{ subgid.stdout }}"
+ setype: _default
+
+- name: Link config directory
+ ansible.builtin.file:
+ dest: /srv/nodered
+ src: /export/nodered
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+
+- name: Create service file
+ ansible.builtin.template:
+ dest: /etc/systemd/system/nodered-container.service
+ src: nodered-container.service.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nodered
+
+- name: Enable service
+ ansible.builtin.service:
+ name: nodered-container
+ state: started
+ enabled: true
+
+- name: Copy nginx config
+ ansible.builtin.copy:
+ dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/00-nodered.conf"
+ content: |
+ location /nodered/ {
+ proxy_pass http://127.0.0.1:8012/;
+ }
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
diff --git a/roles/nodered/templates/nodered-container.service.j2 b/roles/nodered/templates/nodered-container.service.j2
new file mode 100644
index 0000000..fa188a7
--- /dev/null
+++ b/roles/nodered/templates/nodered-container.service.j2
@@ -0,0 +1,18 @@
+[Unit]
+Description=NodeRed Container
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+User=nodered
+ExecStart=/usr/bin/podman run \
+ --rm -p 127.0.0.1:8012:1880 \
+ --name nodered \
+ --env TZ=Europe/Helsinki \
+ --volume /srv/nodered:/data:rw \
+ docker.io/nodered/node-red:{{ nodered_version }}
+ExecStop=/usr/bin/podman stop --ignore nodered
+ExecStopPost=/usr/bin/podman rm -f --ignore nodered
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/nsd/tasks/main.yml b/roles/nsd/tasks/main.yml
index 930a01d..da21b4f 100644
--- a/roles/nsd/tasks/main.yml
+++ b/roles/nsd/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
dest: "{{ tls_private }}/{{ nsd_server }}.key"
src: "{{ item }}"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
with_first_found:
@@ -17,7 +17,7 @@
ansible.builtin.copy:
dest: "{{ tls_certs }}/{{ nsd_server }}.crt"
src: "{{ item }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
with_first_found:
@@ -31,7 +31,7 @@
ansible.builtin.template:
src: nsd.conf.j2
dest: /var/nsd/etc/nsd.conf
- mode: 0640
+ mode: "0640"
owner: root
group: _nsd
notify: Restart nsd
@@ -40,9 +40,10 @@
ansible.builtin.copy:
dest: "/var/nsd/zones/master/{{ item | replace('/', '-') }}"
src: "/srv/dns/{{ item | replace('/', '-') }}"
- mode: 0640
+ mode: "0640"
owner: root
group: _nsd
+ validate: "nsd-checkzone '{{ item }}' '%s'"
tags: dns
notify: Restart nsd
with_items: "{{ nsd_zones }}"
diff --git a/roles/nsd/templates/nsd.conf.j2 b/roles/nsd/templates/nsd.conf.j2
index 60251c1..9e8afec 100644
--- a/roles/nsd/templates/nsd.conf.j2
+++ b/roles/nsd/templates/nsd.conf.j2
@@ -7,10 +7,10 @@ server:
server-count: {{ ansible_processor_count }}
verbosity: 2
- interface: ::0@53
- interface: 0.0.0.0@53
- interface: ::0@853
- interface: 0.0.0.0@853
+{% for ip in ansible_all_ipv4_addresses + ansible_all_ipv6_addresses %}
+ interface: {{ ip }}@53
+ interface: {{ ip }}@853
+{% endfor %}
tls-service-key: {{ tls_private }}/{{ nsd_server }}.key
tls-service-pem: {{ tls_certs }}/{{ nsd_server }}.crt
diff --git a/roles/openbgpd/tasks/main.yml b/roles/openbgpd/tasks/main.yml
index 94e78fe..736ce90 100644
--- a/roles/openbgpd/tasks/main.yml
+++ b/roles/openbgpd/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
dest: /etc/bgpd.conf
src: "{{ ansible_private }}/files/bgpd/bgpd.conf.{{ inventory_hostname }}"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart bgpd
diff --git a/roles/opendkim/defaults/main.yml b/roles/opendkim/defaults/main.yml
new file mode 100644
index 0000000..ae208c6
--- /dev/null
+++ b/roles/opendkim/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+opendkim_selector: default
diff --git a/roles/opendkim/files/keystore.Makefile b/roles/opendkim/files/keystore.Makefile
new file mode 100644
index 0000000..1a04593
--- /dev/null
+++ b/roles/opendkim/files/keystore.Makefile
@@ -0,0 +1,28 @@
+TARGETS := $(shell { \
+ if [ $$(date +%m) -lt 6 ]; then \
+ echo "$$(date +%Y)0101.key $$(date +%Y)0601.key" ; \
+ else \
+ echo "$$(date +%Y)0601.key $$(($$(date +%Y) + 1))0101.key" ; \
+ fi \
+ })
+
+all: $(TARGETS)
+
+%.key:
+ @set -eu ; \
+ openssl genrsa -out "$@" 2048 ; \
+ chgrp opendkim "$@" ; \
+ chmod 0640 "$@" ; \
+ echo ; \
+ data="$$(printf "v=DKIM1; k=rsa; p=%s" \
+ "$$(openssl rsa -in "$@" -pubout -outform der 2>/dev/null | openssl base64 -A)")" ; \
+ pos=0 ; \
+ printf "%s._domainkey\tIN\tTXT\t" "$$(echo "$@" | cut -d. -f1)" ; \
+ while true ; do \
+ printf "\"%s\"" \
+ "$$(echo "$$data" | cut -c $$((pos + 1))-$$((pos + 254)))" ; \
+ pos="$$((pos + 254))" ; \
+ [ $${#data} -gt $$pos ] || break ; \
+ printf " " ; \
+ done ; \
+ echo
diff --git a/roles/opendkim/handlers/main.yml b/roles/opendkim/handlers/main.yml
new file mode 100644
index 0000000..e98da1b
--- /dev/null
+++ b/roles/opendkim/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart opendkim
+ ansible.builtin.service:
+ name: opendkim
+ state: restarted
diff --git a/roles/opendkim/tasks/main.yml b/roles/opendkim/tasks/main.yml
new file mode 100644
index 0000000..7c1001a
--- /dev/null
+++ b/roles/opendkim/tasks/main.yml
@@ -0,0 +1,85 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: opendkim
+ state: installed
+
+- name: Fix SELinux contexts from keystore
+ community.general.sefcontext:
+ path: "/export/dkim(/.*)?"
+ setype: etc_t
+
+- name: Create keystore
+ ansible.builtin.file:
+ path: /export/dkim
+ state: directory
+ mode: "0710"
+ owner: root
+ group: opendkim
+ setype: _default
+
+- name: Link keystore
+ ansible.builtin.file:
+ dest: /srv/dkim
+ src: /export/dkim
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+
+- name: Add keystore Makefile
+ ansible.builtin.copy:
+ dest: /srv/dkim/Makefile
+ src: keystore.Makefile
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ setype: _default
+
+- name: Set selector
+ ansible.builtin.lineinfile:
+ path: /etc/opendkim.conf
+ regexp: '^(# )?Selector\s'
+ line: "Selector\t{{ opendkim_selector }}"
+ notify: Restart opendkim
+
+- name: Set key file path
+ ansible.builtin.lineinfile:
+ path: /etc/opendkim.conf
+ regexp: '^(# )?KeyFile\s'
+ line: "KeyFile\t/srv/dkim/{{ opendkim_selector }}.key"
+ notify: Restart opendkim
+
+- name: Enable signing and verifying messages
+ ansible.builtin.lineinfile:
+ path: /etc/opendkim.conf
+ regexp: '^(# )?Mode\s'
+ line: "Mode\tsv"
+ notify: Restart opendkim
+
+- name: Configure signing domains
+ ansible.builtin.lineinfile:
+ path: /etc/opendkim.conf
+ regexp: '^(# )?Domain\s'
+ line: "Domain\t{{ mail_domain }}"
+ notify: Restart opendkim
+
+- name: Configure report address
+ ansible.builtin.lineinfile:
+ path: /etc/opendkim.conf
+ regexp: '^(# )?ReportAddress\s'
+ line: "ReportAddress\tpostmaster@{{ mail_domain }}"
+ notify: Restart opendkim
+
+- name: Don't add DKIM-Filter header
+ ansible.builtin.lineinfile:
+ path: /etc/opendkim.conf
+ regexp: '^(# )?SoftwareHeader\s'
+ line: "SoftwareHeader\tno"
+ notify: Restart opendkim
+
+- name: Enable service
+ ansible.builtin.service:
+ name: opendkim
+ state: started
+ enabled: true
diff --git a/roles/opensmtpd/tasks/main.yml b/roles/opensmtpd/tasks/main.yml
index 243a1e0..40e1891 100644
--- a/roles/opensmtpd/tasks/main.yml
+++ b/roles/opensmtpd/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.template:
src: smtpd.conf.j2
dest: /etc/mail/smtpd.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart opensmtpd
@@ -12,7 +12,7 @@
ansible.builtin.copy:
content: "{{ mail_domain }}\n"
dest: /etc/mail//mailname
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart opensmtpd
diff --git a/roles/openvpn/files/hostname.tap0 b/roles/openvpn/files/hostname.tap0
index cd1c353..2b44eb9 100644
--- a/roles/openvpn/files/hostname.tap0
+++ b/roles/openvpn/files/hostname.tap0
@@ -1,2 +1,2 @@
up
-!/usr/local/sbin/openvpn --daemon --config /etc/openvpn/tap0.conf
+!/sbin/route -T 1 exec /usr/local/sbin/openvpn --daemon --config /etc/openvpn/tap0.conf
diff --git a/roles/openvpn/tasks/main.yml b/roles/openvpn/tasks/main.yml
index 7f1edca..84b8d2b 100644
--- a/roles/openvpn/tasks/main.yml
+++ b/roles/openvpn/tasks/main.yml
@@ -8,7 +8,7 @@
ansible.builtin.file:
path: /var/openvpn
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: _openvpn
@@ -16,7 +16,7 @@
ansible.builtin.file:
path: /var/openvpn/tmp
state: directory
- mode: 0770
+ mode: "0770"
owner: _openvpn
group: _openvpn
@@ -24,7 +24,7 @@
ansible.builtin.file:
path: /etc/openvpn
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -32,7 +32,7 @@
ansible.builtin.file:
path: /etc/openvpn/keys
state: directory
- mode: 0700
+ mode: "0700"
owner: root
group: "{{ ansible_wheel }}"
@@ -40,7 +40,7 @@
ansible.builtin.copy:
src: "{{ ansible_private }}/files/openvpn/{{ inventory_hostname }}.key"
dest: /etc/openvpn/keys/tap0.key
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
@@ -48,7 +48,7 @@
ansible.builtin.copy:
src: "{{ ansible_private }}/files/openvpn/{{ inventory_hostname }}.conf"
dest: /etc/openvpn/tap0.conf
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
@@ -56,6 +56,6 @@
ansible.builtin.copy:
src: hostname.tap0
dest: /etc/hostname.tap0
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/pf/files/pf.conf.gw_fsol b/roles/pf/files/pf.conf.gw_fsol
index c6bfb1b..48215c0 100644
--- a/roles/pf/files/pf.conf.gw_fsol
+++ b/roles/pf/files/pf.conf.gw_fsol
@@ -30,9 +30,9 @@ pass quick inet6 proto icmp6
antispoof for lo0
antispoof for vio0
-# admin connection and munin (internal)
+# admin connection and node_exporter (internal)
pass in quick on $int_if proto tcp from $int_net to self port ssh keep state (no-sync)
-pass in quick on $int_if proto tcp from $int_net to self port 4949 keep state (no-sync)
+pass in quick on $int_if proto tcp from $int_net to self port 9100 keep state (no-sync)
# internal network
block in quick from any to self
diff --git a/roles/pf/files/pf.conf.gw_home b/roles/pf/files/pf.conf.gw_home
index a71029d..3f211fb 100644
--- a/roles/pf/files/pf.conf.gw_home
+++ b/roles/pf/files/pf.conf.gw_home
@@ -39,14 +39,15 @@ antispoof for lo0
antispoof for vio0
antispoof for vio1
-# admin connection (internal, fsol and arc office)
+# admin connection (internal, arcsec office, dmz, lan)
pass in quick on $int_if proto tcp from $int_net to self port ssh
pass in quick on $ext_if proto tcp from 37.35.86.64/29 to self port ssh
pass in quick on $ext_if proto tcp from 37.16.96.144/28 to self port ssh
-pass in quick on $ext_if proto tcp from 81.175.155.142/32 to self port ssh
+pass in quick on $ext_if proto tcp from 212.149.225.198/32 to self port ssh
-# munin from internal network
-pass in quick on $int_if proto tcp from $int_net to self port 4949
+# node_exporter and unbound_exporter from internal network
+pass in quick on $int_if proto tcp from $int_net to self port 9100
+pass in quick on $int_if proto tcp from $int_net to self port 9167
# allow dns queries from internal net
pass in quick on $int_if proto { tcp, udp } from $int_net to self port domain
diff --git a/roles/pf/tasks/main.yml b/roles/pf/tasks/main.yml
index 578a0d6..588dac6 100644
--- a/roles/pf/tasks/main.yml
+++ b/roles/pf/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
src: "{{ firewall_src }}"
dest: /etc/pf.conf
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
validate: pfctl -N -f %s
@@ -14,7 +14,7 @@
ansible.builtin.template:
src: pf.conf.j2
dest: /etc/pf.conf
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
validate: pfctl -N -f %s
diff --git a/roles/php4dvd/handlers/main.yml b/roles/php4dvd/handlers/main.yml
new file mode 100644
index 0000000..bc94087
--- /dev/null
+++ b/roles/php4dvd/handlers/main.yml
@@ -0,0 +1,17 @@
+---
+- name: Rebuild php4dvd-container
+ ansible.builtin.command:
+ argv:
+ - podman
+ - build
+ - -t
+ - php4dvd
+ - /usr/local/src/docker-php4dvd
+ become: true
+ become_user: php4dvd
+ notify: Restart php4dvd-container
+
+- name: Restart php4dvd-container
+ ansible.builtin.service:
+ name: php4dvd-container
+ state: restarted
diff --git a/roles/php4dvd/meta/main.yml b/roles/php4dvd/meta/main.yml
new file mode 100644
index 0000000..b8e2a3e
--- /dev/null
+++ b/roles/php4dvd/meta/main.yml
@@ -0,0 +1,5 @@
+---
+dependencies:
+ - {role: git}
+ - {role: nginx}
+ - {role: podman}
diff --git a/roles/php4dvd/tasks/main.yml b/roles/php4dvd/tasks/main.yml
new file mode 100644
index 0000000..749a032
--- /dev/null
+++ b/roles/php4dvd/tasks/main.yml
@@ -0,0 +1,71 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: php4dvd
+
+- name: Create user
+ ansible.builtin.user:
+ name: php4dvd
+ comment: Podman pphp4dvd
+ group: php4dvd
+ shell: /sbin/nologin
+
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - php4dvd
+ creates: /var/lib/systemd/linger/php4dvd
+
+- name: Copy host key
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/php4dvd.key"
+ src: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ mode: "0640"
+ owner: root
+ group: php4dvd
+ remote_src: true
+
+- name: Get container source
+ ansible.builtin.git:
+ dest: /usr/local/src/docker-php4dvd
+ repo: https://github.com/foo-sh/docker-php4dvd.git
+ update: true
+ version: master
+ notify: Rebuild php4dvd-container
+
+- name: Create service file
+ ansible.builtin.template:
+ dest: /etc/systemd/system/php4dvd-container.service
+ src: php4dvd-container.service.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create service config
+ ansible.builtin.template:
+ dest: /etc/sysconfig/php4dvd-container
+ src: php4dvd-container.sysconfig.j2
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart php4dvd-container
+
+- name: Enable service
+ ansible.builtin.service:
+ name: php4dvd-container
+ state: started
+ enabled: true
+
+- name: Copy nginx config
+ ansible.builtin.copy:
+ dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/php4dvd-container.conf"
+ content: |
+ location /php4dvd {
+ proxy_pass http://127.0.0.1:8005/;
+ }
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
diff --git a/roles/php4dvd/templates/php4dvd-container.service.j2 b/roles/php4dvd/templates/php4dvd-container.service.j2
new file mode 100644
index 0000000..af646cb
--- /dev/null
+++ b/roles/php4dvd/templates/php4dvd-container.service.j2
@@ -0,0 +1,22 @@
+[Unit]
+Description=php4dvd Container
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+User=php4dvd
+EnvironmentFile=/etc/sysconfig/php4dvd-container
+ExecStart=/usr/bin/podman run \
+ --rm -p 127.0.0.1:8005:80 \
+ --name php4dvd \
+ --env PHP4DVD_* \
+ --volume={{ tls_certs }}/ca.crt:/etc/ssl/certs/ca.crt:ro \
+ --volume={{ tls_certs }}/{{ inventory_hostname }}.crt:/etc/ssl/certs/{{ inventory_hostname }}.crt:ro \
+ --volume={{ tls_private }}/php4dvd.key:/etc/ssl/private/{{ inventory_hostname }}.key:ro \
+ --volume /export/volumes/php4dvd:/var/www/html/movies:rw,Z \
+ php4dvd:latest
+ExecStop=/usr/bin/podman stop --ignore php4dvd
+ExecStopPost=/usr/bin/podman rm -f --ignore php4dvd
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/php4dvd/templates/php4dvd-container.sysconfig.j2 b/roles/php4dvd/templates/php4dvd-container.sysconfig.j2
new file mode 100644
index 0000000..79c274b
--- /dev/null
+++ b/roles/php4dvd/templates/php4dvd-container.sysconfig.j2
@@ -0,0 +1,8 @@
+PHP4DVD_DB_HOST=sqldb02.home.foo.sh
+PHP4DVD_DB_NAME=php4dvd
+PHP4DVD_DB_USER=php4dvd
+PHP4DVD_DB_PASS={{ php4dvd_mysql_pass }}
+PHP4DVD_DB_KEY=/etc/ssl/private/{{ inventory_hostname }}.key
+PHP4DVD_DB_CERT=/etc/ssl/certs/{{ inventory_hostname }}.crt
+PHP4DVD_DB_CACERT=/etc/ssl/certs/ca.crt
+PHP4DVD_USER_GUESTVIEW=true
diff --git a/roles/pki/files/mtree.patch b/roles/pki/files/mtree.patch
new file mode 100644
index 0000000..17ce41e
--- /dev/null
+++ b/roles/pki/files/mtree.patch
@@ -0,0 +1,11 @@
+--- 4.4BSD.dist.orig Fri Dec 22 17:31:46 2023
++++ 4.4BSD.dist Fri Dec 22 17:32:00 2023
+@@ -105,7 +105,7 @@
+
+ # ./etc/ssl
+ ssl
+- private uname=root mode=0700
++ private gname=hostkey uname=root mode=0750
+ ..
+ ..
+
diff --git a/roles/pki/tasks/main.yml b/roles/pki/tasks/main.yml
index 020211e..90d160e 100644
--- a/roles/pki/tasks/main.yml
+++ b/roles/pki/tasks/main.yml
@@ -8,7 +8,7 @@
ansible.builtin.copy:
src: "/srv/ca/certs/ca.crt"
dest: "{{ tls_certs }}/ca.crt"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -24,15 +24,22 @@
delegate_to: localhost
register: result
changed_when: false
+ check_mode: false
- name: Store ca certificate hash
ansible.builtin.set_fact:
pki_cacert_hash: "{{ result.stdout }}"
+- name: Patch mtree to set correct permissions on /etc/ssl/private
+ ansible.posix.patch:
+ dest: /etc/mtree/4.4BSD.dist
+ src: mtree.patch
+ when: ansible_system == "OpenBSD"
+
- name: Fix private key directory permissions
ansible.builtin.file:
path: "{{ tls_private }}"
- mode: 0750
+ mode: "0750"
owner: root
group: hostkey
when: ansible_system == "OpenBSD"
@@ -41,7 +48,7 @@
ansible.builtin.copy:
src: "/srv/ca/certs/hosts/{{ inventory_hostname }}.crt"
dest: "{{ tls_certs }}/{{ inventory_hostname }}.crt"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -56,7 +63,7 @@
' {{ tls_certs }}/{{ inventory_hostname }}.crt
dest: /etc/ansible/facts.d/ansible_certificate.fact
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -67,13 +74,14 @@
- "{{ tls_certs }}/{{ inventory_hostname }}.crt"
- "{{ tls_certs }}/ca.crt"
changed_when: false
+ check_mode: false
register: pki_host_fullchain
- name: Copy full chain certificate file
ansible.builtin.copy:
dest: "{{ tls_certs }}/{{ inventory_hostname }}-fullchain.crt"
content: "{{ pki_host_fullchain.stdout }}"
- mode: 0640
+ mode: "0640"
owner: root
group: "{{ ansible_wheel }}"
@@ -81,6 +89,6 @@
ansible.builtin.copy:
src: "/srv/ca/private/{{ inventory_hostname }}.key"
dest: "{{ tls_private }}/{{ inventory_hostname }}.key"
- mode: 0640
+ mode: "0640"
owner: root
group: hostkey
diff --git a/roles/podman/meta/main.yml b/roles/podman/meta/main.yml
deleted file mode 100644
index b95ceec..0000000
--- a/roles/podman/meta/main.yml
+++ /dev/null
@@ -1,3 +0,0 @@
----
-dependencies:
- - {role: nginx/server}
diff --git a/roles/podman/tasks/main.yml b/roles/podman/tasks/main.yml
index f574e4c..93660dd 100644
--- a/roles/podman/tasks/main.yml
+++ b/roles/podman/tasks/main.yml
@@ -14,7 +14,7 @@
ansible.builtin.copy:
dest: /usr/local/share/selinux/podman-certs.pp
src: podman-certs.pp
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/prometheus/handlers/main.yml b/roles/prometheus/handlers/main.yml
new file mode 100644
index 0000000..690e0bd
--- /dev/null
+++ b/roles/prometheus/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart prometheus
+ ansible.builtin.service:
+ name: prometheus
+ state: restarted
diff --git a/roles/prometheus/meta/main.yml b/roles/prometheus/meta/main.yml
new file mode 100644
index 0000000..1e5084e
--- /dev/null
+++ b/roles/prometheus/meta/main.yml
@@ -0,0 +1,4 @@
+---
+dependencies:
+ - {role: epel_repo}
+ - {role: nginx}
diff --git a/roles/prometheus/tasks/main.yml b/roles/prometheus/tasks/main.yml
new file mode 100644
index 0000000..eb47818
--- /dev/null
+++ b/roles/prometheus/tasks/main.yml
@@ -0,0 +1,100 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: prometheus
+ gid: 305
+
+- name: Create user
+ ansible.builtin.user:
+ name: prometheus
+ comment: Service Prometheus
+ createhome: false
+ group: prometheus
+ home: /var/empty
+ shell: /sbin/nologin
+ uid: 305
+
+- name: Install packages
+ ansible.builtin.package:
+ name: golang-github-prometheus
+ state: installed
+
+- name: Create data directory
+ ansible.builtin.file:
+ path: /export/prometheus
+ state: directory
+ mode: "0770"
+ owner: root
+ group: prometheus
+
+- name: Link data directory
+ ansible.builtin.file:
+ path: /srv/prometheus
+ src: /export/prometheus
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+
+- name: Configure startup options
+ ansible.builtin.lineinfile:
+ path: /etc/default/prometheus
+ regexp: "^ARGS="
+ line: >-
+ ARGS="--config.file=/etc/prometheus/prometheus.yml
+ --log.level=info
+ --storage.tsdb.path=/srv/prometheus
+ --storage.tsdb.retention.time=365d
+ --web.console.libraries=/usr/local/share/prometheus/console_libraries"
+ notify: Restart prometheus
+
+- name: Create configuration
+ ansible.builtin.template:
+ dest: /etc/prometheus/prometheus.yml
+ src: prometheus.yml.j2
+ mode: "0640"
+ owner: root
+ group: prometheus
+ notify: Restart prometheus
+
+- name: Create host config directory
+ ansible.builtin.file:
+ path: /etc/prometheus/node.d
+ state: directory
+ mode: "0750"
+ owner: root
+ group: prometheus
+
+- name: Create host configs
+ ansible.builtin.template:
+ dest: "/etc/prometheus/node.d/{{ item }}.json"
+ src: node.json.j2
+ mode: "0640"
+ owner: root
+ group: prometheus
+ notify: Restart prometheus
+ with_items: "{{ groups['all'] }}"
+
+- name: Enable service
+ ansible.builtin.service:
+ name: prometheus
+ state: started
+ enabled: true
+
+- name: Allow nginx to connect prometheus
+ ansible.posix.seboolean:
+ name: httpd_can_network_connect
+ state: true
+ persistent: true
+
+- name: Copy nginx config
+ ansible.builtin.copy:
+ dest: "/etc/nginx/conf.d/{{ inventory_hostname }}/prometheus.conf"
+ content: |
+ location / {
+ proxy_pass http://127.0.0.1:9090;
+ }
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
diff --git a/roles/prometheus/templates/node.json.j2 b/roles/prometheus/templates/node.json.j2
new file mode 100644
index 0000000..0f4e396
--- /dev/null
+++ b/roles/prometheus/templates/node.json.j2
@@ -0,0 +1,10 @@
+[
+ {
+ "labels": {
+ "instance": "{{ item }}"
+ },
+ "targets": [
+ "{{ item }}:9100"
+ ]
+ }
+]
diff --git a/roles/prometheus/templates/prometheus.yml.j2 b/roles/prometheus/templates/prometheus.yml.j2
new file mode 100644
index 0000000..74aa03f
--- /dev/null
+++ b/roles/prometheus/templates/prometheus.yml.j2
@@ -0,0 +1,82 @@
+---
+global:
+ scrape_interval: 1m
+ scrape_timeout: 10s
+ evaluation_interval: 1m
+
+scrape_configs:
+ - job_name: prometheus
+ static_configs:
+ - targets:
+ - "127.0.0.1:9090"
+
+ - job_name: mysqld
+ scheme: https
+ tls_config:
+ ca_file: "{{ tls_certs }}/ca.crt"
+ key_file: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ cert_file: "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ static_configs:
+ - targets:
+{% for host in groups['sqldb'] %}
+ - {{ host }}:3306
+{% endfor %}
+ relabel_configs:
+ - source_labels: [__address__]
+ target_label: __param_target
+ - source_labels: [__param_target]
+ target_label: instance
+ - target_label: __address__
+ replacement: {{ inventory_hostname }}:9104
+
+ - job_name: nginx
+ scheme: https
+ tls_config:
+ ca_file: "{{ tls_certs }}/ca.crt"
+ key_file: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ cert_file: "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ static_configs:
+ - targets:
+ - {{ inventory_hostname }}:9113
+
+ - job_name: snmp
+ scheme: https
+ tls_config:
+ ca_file: "{{ tls_certs }}/ca.crt"
+ key_file: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ cert_file: "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ static_configs:
+ - targets:
+ - 172.20.25.102
+ metrics_path: /snmp
+ params:
+ auth: [public_v2]
+ module: [if_mib]
+ relabel_configs:
+ - source_labels: [__address__]
+ target_label: __param_target
+ - source_labels: [__param_target]
+ target_label: instance
+ - target_label: __address__
+ replacement: nms.home.foo.sh:9116
+
+ - job_name: unbound
+ scheme: https
+ tls_config:
+ ca_file: "{{ tls_certs }}/ca.crt"
+ key_file: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ cert_file: "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ static_configs:
+ - targets:
+ - dna-gw01.home.foo.sh:9167
+ - dna-gw02.home.foo.sh:9167
+
+ - job_name: node
+ scheme: https
+ tls_config:
+ ca_file: "{{ tls_certs }}/ca.crt"
+ key_file: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ cert_file: "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ file_sd_configs:
+ - files:
+ - /etc/prometheus/node.d/*.json
diff --git a/roles/rclone/templates/rclone-sync.sh.j2 b/roles/rclone/files/rclone-sync.sh
similarity index 70%
rename from roles/rclone/templates/rclone-sync.sh.j2
rename to roles/rclone/files/rclone-sync.sh
index a7aadb6..40323ce 100755
--- a/roles/rclone/templates/rclone-sync.sh.j2
+++ b/roles/rclone/files/rclone-sync.sh
@@ -1,15 +1,21 @@
#!/bin/sh
-set -u
+set -eu
umask 027
-TARGET="{{ destination }}"
-CONFIG="/etc/rclone/rclone.conf"
-LOGDIR="/var/log/rclone"
+SERVICE="$(whoami)"
+
+TARGET="/srv/${SERVICE}"
+CONFIG="/etc/rclone/${SERVICE}.conf"
+LOGDIR="/var/log/rclone/${SERVICE}"
RCLONE="/usr/local/bin/rclone"
timestamp="$(date +%Y%m%d%H%M%S)"
+if [ ! -f "$CONFIG" ]; then
+ echo "ERR: Config file '${CONFIG}' does not exist" 1>&2
+ exit 1
+fi
if [ ! -d "$TARGET" ]; then
echo "ERR: Destination directory '${TARGET}' does not exist" 1>&2
exit 1
@@ -27,3 +33,5 @@ for host in $("$RCLONE" --config "$CONFIG" listremotes | tr -d ":") ; do
cat "$log"
fi
done
+
+find "$LOGDIR" -type f -name "*.log" -mtime +30 -delete
diff --git a/roles/sftpbackup/meta/main.yml b/roles/rclone/meta/main.yml
similarity index 100%
rename from roles/sftpbackup/meta/main.yml
rename to roles/rclone/meta/main.yml
diff --git a/roles/rclone/tasks/main.yml b/roles/rclone/tasks/main.yml
index fe8ba2e..455de9b 100644
--- a/roles/rclone/tasks/main.yml
+++ b/roles/rclone/tasks/main.yml
@@ -8,31 +8,78 @@
ansible.builtin.file:
path: /etc/rclone
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
- name: Create host config
ansible.builtin.template:
- dest: /etc/rclone/rclone.conf
+ dest: "/etc/rclone/{{ rclone_service }}.conf"
src: rclone.conf.j2
- mode: 0644
+ mode: "0640"
+ owner: root
+ group: "{{ rclone_service }}"
+
+- name: Create ssh keys
+ ansible.builtin.command:
+ argv:
+ - ssh-keygen
+ - -t
+ - ed25519
+ - -C
+ - "{{ rclone_service }}@{{ inventory_hostname }}"
+ - -N
+ - ""
+ - -f
+ - "/etc/rclone/ssh_{{ rclone_service }}_ed25519_key"
+ creates: "/etc/rclone/ssh_{{ rclone_service }}_ed25519_key"
+
+- name: Fix ssh key permissions
+ ansible.builtin.file:
+ path: "{{ item }}"
+ owner: root
+ group: "{{ rclone_service }}"
+ mode: "0640"
+ with_items:
+ - "/etc/rclone/ssh_{{ rclone_service }}_ed25519_key"
+ - "/etc/rclone/ssh_{{ rclone_service }}_ed25519_key.pub"
+
+- name: Fetch ssh public key
+ ansible.builtin.fetch:
+ src: "/etc/rclone/ssh_{{ rclone_service }}_ed25519_key.pub"
+ dest: "../files/ssh/{{ rclone_service }}.pub"
+ flat: true
+
+- name: Create base log directory
+ ansible.builtin.file:
+ path: /var/log/rclone
+ state: directory
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
- name: Create log directory
ansible.builtin.file:
- path: /var/log/rclone
+ path: "/var/log/rclone/{{ rclone_service }}"
state: directory
- mode: 0750
- owner: "{{ local_user | default('root') }}"
- group: "{{ local_user | default(ansible_wheel) }}"
+ mode: "0750"
+ owner: "{{ rclone_service }}"
+ group: "{{ rclone_service }}"
+
+- name: Create data directories
+ ansible.builtin.file:
+ path: "/srv/{{ rclone_service }}/{{ item }}"
+ state: directory
+ mode: "0770"
+ owner: root
+ group: "{{ rclone_service }}"
+ with_items: "{{ groups[rclone_hostgroup | default(rclone_service)] }}"
- name: Copy rclone sync script
- ansible.builtin.template:
+ ansible.builtin.copy:
dest: /usr/local/bin/rclone-sync
- src: rclone-sync.sh.j2
- mode: 0755
+ src: rclone-sync.sh
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -40,16 +87,13 @@
ansible.builtin.cron:
name: MAILTO
env: true
- user: "{{ local_user }}"
+ user: "{{ rclone_service }}"
value: root
- when:
- - local_user is defined
- - local_user != "root"
- name: Add rclone sync cron job
ansible.builtin.cron:
name: rclone-sync
- user: "{{ local_user | default('root') }}"
+ user: "{{ rclone_service }}"
hour: "3"
- minute: "{{ 60 | random(seed=inventory_hostname) }}"
+ minute: "00"
job: /usr/local/bin/rclone-sync
diff --git a/roles/rclone/templates/rclone.conf.j2 b/roles/rclone/templates/rclone.conf.j2
index 9389314..bc4f312 100644
--- a/roles/rclone/templates/rclone.conf.j2
+++ b/roles/rclone/templates/rclone.conf.j2
@@ -1,10 +1,11 @@
# {{ ansible_managed }}
-{% for host in groups[hostgroup] %}
+{% for host in groups[rclone_hostgroup | default(rclone_service)] %}
[{{ host.split('.')[0] }}]
type = sftp
host = {{ host }}
-user = {{ remote_user }}
-key_file = {{ private_key | default('~/.ssh/id_ed25519') }}
-known_hosts_file = /etc/ssh/ssh_known_hosts
+user = {{ rclone_service }}
+shell_type = none
+key_file = /etc/rclone/ssh_{{ rclone_service }}_ed25519_key
+known_hosts_file = /etc/ssh/ssh_known_hosts
{% endfor %}
diff --git a/roles/relayd/tasks/main.yml b/roles/relayd/tasks/main.yml
index 35befda..1e82b13 100644
--- a/roles/relayd/tasks/main.yml
+++ b/roles/relayd/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.template:
dest: /etc/relayd.conf
src: relayd.conf.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
validate: "relayd -n -f %s"
diff --git a/roles/reportmirror/defaults/main.yml b/roles/reportmirror/defaults/main.yml
new file mode 100644
index 0000000..934a0e9
--- /dev/null
+++ b/roles/reportmirror/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+reportmirror_hostname: "{{ inventory_hostname }}"
+reportmirror_mirrors: []
diff --git a/roles/mirror/reportmirror/meta/main.yml b/roles/reportmirror/meta/main.yml
similarity index 100%
rename from roles/mirror/reportmirror/meta/main.yml
rename to roles/reportmirror/meta/main.yml
diff --git a/roles/mirror/reportmirror/tasks/main.yml b/roles/reportmirror/tasks/main.yml
similarity index 92%
rename from roles/mirror/reportmirror/tasks/main.yml
rename to roles/reportmirror/tasks/main.yml
index 193fa2e..487027d 100644
--- a/roles/mirror/reportmirror/tasks/main.yml
+++ b/roles/reportmirror/tasks/main.yml
@@ -8,13 +8,14 @@
ansible.builtin.git:
dest: /usr/local/src/report_mirror
repo: https://github.com/fedora-infra/mirrormanager2.git
+ update: true
version: master
- name: Install reportmirror script
ansible.builtin.copy:
dest: /usr/local/bin/report_mirror
src: /usr/local/src/report_mirror/client/report_mirror
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
remote_src: true
@@ -23,7 +24,7 @@
ansible.builtin.file:
dest: /etc/mirrormanager-client
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: mirror
@@ -31,6 +32,6 @@
ansible.builtin.template:
dest: /etc/mirrormanager-client/report_mirror.conf
src: report_mirror.conf.j2
- mode: 0640
+ mode: "0640"
owner: root
group: mirror
diff --git a/roles/mirror/reportmirror/templates/report_mirror.conf.j2 b/roles/reportmirror/templates/report_mirror.conf.j2
similarity index 91%
rename from roles/mirror/reportmirror/templates/report_mirror.conf.j2
rename to roles/reportmirror/templates/report_mirror.conf.j2
index ae793f3..7181a22 100644
--- a/roles/mirror/reportmirror/templates/report_mirror.conf.j2
+++ b/roles/reportmirror/templates/report_mirror.conf.j2
@@ -11,8 +11,8 @@ enabled=1
# Name and Password fields need to match the Site name and password
# fields you entered for your Site in the MirrorManager database at
# https://admin.fedoraproject.org/mirrormanager
-name={{ sitename }}
-password={{ password }}
+name={{ reportmirror_sitename }}
+password={{ reportmirror_password }}
[host]
# if enabled=0, no data about this host is sent to the database
@@ -20,7 +20,7 @@ enabled=1
# Name field need to match the Host name field you entered for your
# Host in the MirrorManager database at
# https://admin.fedoraproject.org/mirrormanager
-name={{ hostname }}
+name={{ reportmirror_hostname }}
# if user_active=0, no data about this category is given to the public
# This can be used to toggle between serving and not serving data,
# such enabled during the nighttime (when you have more idle bandwidth
@@ -52,15 +52,15 @@ rsyncd=/var/log/rsyncd.log
# path= is the path on your local disk to the top-level directory for this Category
[Fedora Linux]
-{% if "fedora" in mirrors %}
+{% if "fedora" in reportmirror_mirrors %}
enabled=1
{% else %}
enabled=0
{% endif %}
path=/srv/mrirors/fedora
-[Fedora EPEL]
-{% if "epel" in mirrors %}
+[Fedora EPELreport]
+{% if "epel" in reportmirror_mirrors %}
enabled=1
{% else %}
enabled=0
diff --git a/roles/rocketchat/defaults/main.yml b/roles/rocketchat/defaults/main.yml
new file mode 100644
index 0000000..6b40b0a
--- /dev/null
+++ b/roles/rocketchat/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+rocketchat_versin: default
diff --git a/roles/rocketchat/handlers/main.yml b/roles/rocketchat/handlers/main.yml
new file mode 100644
index 0000000..93b2616
--- /dev/null
+++ b/roles/rocketchat/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart rocketchat
+ ansible.builtin.systemd:
+ name: rocketchat-container
+ daemon_reload: true
+ state: restarted
diff --git a/roles/rocketchat/meta/main.yml b/roles/rocketchat/meta/main.yml
new file mode 100644
index 0000000..700494e
--- /dev/null
+++ b/roles/rocketchat/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: podman}
diff --git a/roles/rocketchat/tasks/main.yml b/roles/rocketchat/tasks/main.yml
new file mode 100644
index 0000000..da102d0
--- /dev/null
+++ b/roles/rocketchat/tasks/main.yml
@@ -0,0 +1,84 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: rocketchat
+
+- name: Create user
+ ansible.builtin.user:
+ name: rocketchat
+ comment: Podman Rocket.Chat
+ group: rocketchat
+ shell: /sbin/nologin
+
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - rocketchat
+ creates: /var/lib/systemd/linger/rocketchat
+
+- name: Generate combined certificate/private key file contents
+ ansible.builtin.command:
+ argv:
+ - /bin/cat
+ - "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ - "{{ tls_private }}/{{ inventory_hostname }}.key"
+ changed_when: false
+ check_mode: false
+ register: rocketchat_cert_key
+
+- name: Get rocketchat subgid value
+ ansible.builtin.command:
+ argv:
+ - sed
+ - -n
+ - 's/^rocketchat:\([0-9]\+\):[0-9]\+$/\1/p'
+ - /etc/subuid
+ changed_when: false
+ register: result
+
+- name: Create combined certificate/private key file
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/rocketchat.pem"
+ content: "{{ rocketchat_cert_key.stdout }}"
+ mode: "0640"
+ owner: root
+ group: "{{ result.stdout | int + 65532 }}"
+ notify: Restart rocketchat
+
+- name: Create service config
+ ansible.builtin.template:
+ dest: /etc/sysconfig/rocketchat-container
+ src: rocketchat-container.sysconfig.j2
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart rocketchat
+
+- name: Create service file
+ ansible.builtin.template:
+ dest: /etc/systemd/system/rocketchat-container.service
+ src: rocketchat-container.service.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart rocketchat
+
+- name: Enable service
+ ansible.builtin.service:
+ name: rocketchat-container
+ state: started
+ enabled: true
+
+- name: Copy nginx config
+ ansible.builtin.copy:
+ dest: /etc/nginx/conf.d/{{ inventory_hostname }}/rocketchat-container.conf
+ content: |
+ location /rocketchat/ {
+ proxy_pass http://127.0.0.1:8008/;
+ }
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart nginx
diff --git a/roles/rocketchat/templates/rocketchat-container.service.j2 b/roles/rocketchat/templates/rocketchat-container.service.j2
new file mode 100644
index 0000000..16f511a
--- /dev/null
+++ b/roles/rocketchat/templates/rocketchat-container.service.j2
@@ -0,0 +1,21 @@
+[Unit]
+Description=Rocket.Chat Container
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+User=rocketchat
+EnvironmentFile=/etc/sysconfig/rocketchat-container
+ExecStartPre=/usr/bin/podman pull docker.io/rocketchat/rocket.chat:{{ rocketchat_version }}
+ExecStart=/usr/bin/podman run \
+ --rm -p 127.0.0.1:8008:3000 \
+ --name rocketchat \
+ --volume={{ tls_certs }}/ca.crt:/etc/ssl/certs/ca.crt:ro \
+ --volume={{ tls_private }}/rocketchat.pem:/etc/ssl/private/rocketchat.pem:ro \
+ --env ROOT_URL --env MONGO_URL --env MONGO_OPLOG_URL \
+ docker.io/rocketchat/rocket.chat:{{ rocketchat_version }}
+ExecStop=/usr/bin/podman stop --ignore rocketchat
+ExecStopPost=/usr/bin/podman rm -f --ignore rocketchat
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/rocketchat/templates/rocketchat-container.sysconfig.j2 b/roles/rocketchat/templates/rocketchat-container.sysconfig.j2
new file mode 100644
index 0000000..e023f32
--- /dev/null
+++ b/roles/rocketchat/templates/rocketchat-container.sysconfig.j2
@@ -0,0 +1,3 @@
+ROOT_URL="https://chat.foo.sh/"
+MONGO_URL="mongodb://rocketchat:{{ rocketchat_mongodb_pass }}@mongodb01.home.foo.sh:27017/rocketchat?tls=true&tlscafile=/etc/ssl/certs/ca.crt&tlscertificatekeyfile=/etc/ssl/private/rocketchat.pem"
+MONGO_OPLOG_URL="mongodb://mongodb01.home.foo.sh:27017/local"
diff --git a/roles/roles_lists/tasks/main.yml b/roles/roles_lists/tasks/main.yml
index 5783bbf..049c0ef 100644
--- a/roles/roles_lists/tasks/main.yml
+++ b/roles/roles_lists/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
dest: /etc/smrsh/archiver
src: archiver.sh
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -20,7 +20,7 @@
ansible.builtin.copy:
dest: /usr/local/share/selinux/sendmail-spamc.pp
src: sendmail-spamc.pp
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/roundcube/tasks/main.yml b/roles/roundcube/tasks/main.yml
index a3f66ec..787a983 100644
--- a/roles/roundcube/tasks/main.yml
+++ b/roles/roundcube/tasks/main.yml
@@ -10,11 +10,19 @@
group: roundcube
shell: /sbin/nologin
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - roundcube
+ creates: /var/lib/systemd/linger/roundcube
+
- name: Copy host key
ansible.builtin.copy:
dest: "{{ tls_private }}/roundcube.key"
src: "{{ tls_private }}/{{ inventory_hostname }}.key"
- mode: 0640
+ mode: "0640"
owner: root
group: roundcube
remote_src: true
@@ -23,7 +31,7 @@
ansible.builtin.file:
path: /etc/roundcube
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -31,7 +39,7 @@
ansible.builtin.template:
dest: /etc/roundcube/local.php
src: local.php.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -39,7 +47,7 @@
ansible.builtin.template:
dest: /etc/sysconfig/roundcube-container
src: roundcube-container.sysconfig.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart roundcube
@@ -48,7 +56,7 @@
ansible.builtin.template:
dest: /etc/systemd/system/roundcube-container.service
src: roundcube-container.service.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart roundcube
@@ -66,7 +74,7 @@
location /roundcube/ {
proxy_pass http://localhost:8004/;
}
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart nginx
diff --git a/roles/roundcube/templates/local.php.j2 b/roles/roundcube/templates/local.php.j2
index 2935f09..ea54a4b 100644
--- a/roles/roundcube/templates/local.php.j2
+++ b/roles/roundcube/templates/local.php.j2
@@ -3,4 +3,11 @@
$config["domain"] = "{{ mail_domain }}";
$config["product_name"] = "foo.sh - Webmail";
+$config["plugins"] = array(
+ "database_attachments",
+);
+
+$config['database_attachments_cache'] = 'db';
+$config['database_attachments_cache_ttl'] = 12 * 60 * 60;
+
?>
diff --git a/roles/routeros/files/README.md b/roles/routeros/files/README.md
new file mode 100644
index 0000000..9e5cc1e
--- /dev/null
+++ b/roles/routeros/files/README.md
@@ -0,0 +1,22 @@
+# Mikrotik Routeros Cheat Sheet
+
+## Update
+
+```
+/system package update print
+/tool fetch url=https://oob.foo.sh/routeros/routeros-7.13.4-arm.npk
+/system reboot
+/system package update print
+```
+
+## Change port vlan
+
+```
+/interface/bridge/port/set [find where bridge=bridge and interface=ether1] pvid=30
+```
+
+## Add name to port
+
+```
+/interface/ethernet/set [ find default-name=ether20 ] comment="name"
+```
diff --git a/roles/routeros/files/download-routeros-firmware.sh b/roles/routeros/files/download-routeros-firmware.sh
new file mode 100755
index 0000000..96260ca
--- /dev/null
+++ b/roles/routeros/files/download-routeros-firmware.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+set -eu
+
+umask 022
+
+cd /srv/web/oob.foo.sh/routeros
+
+verbose=false
+if [ "${1:-}" = "-v" ]; then
+ verbose=true
+ shift
+fi
+
+if [ $# -gt 0 ]; then
+ echo "Usage: $(basename "$0") [-v]" 1>&2
+ exit 1
+fi
+
+packageinfo=$(curl -sSf "https://mikrotik.com/download" | awk -F '"' '
+ {
+ if (!url && $0 ~ /routeros-[0-9\.]+-arm.npk/) {
+ url=$2
+ } else if (!found && url && $0 ~ /data-checksum-sha256/) {
+ print url " " $6
+ found = 1
+ }
+ }
+ ')
+
+packageurl="$(echo "$packageinfo" | cut -d " " -f 1)"
+checksum="$(echo "$packageinfo" | cut -d " " -f 2)"
+if [ -z "$packageurl" ]; then
+ echo "ERR: Got empty package URL, exiting" 1>&2
+ exit 1
+fi
+packagename="$(basename "$packageurl")"
+if [ -f "$packagename" ]; then
+ "$verbose" && echo "Already up to date"
+ exit 0
+fi
+
+if [ -z "$checksum" ]; then
+ echo "ERR: Failed to determine package checksum" 1>&2
+ exit 1
+fi
+
+echo "Downloading new package '${packagename}'"
+tmpfile="$(mktemp -p .)"
+trap 'rm -f -- "$tmpfile"' EXIT
+curl -sSf -o "$tmpfile" "$packageurl"
+
+if [ "$(sha256sum "$tmpfile" | cut -d " " -f 1)" != "$checksum" ]; then
+ echo "ERR: Checksum check failed, not saving package" 1>&2
+ exit 1
+fi
+
+mv "$tmpfile" "$packagename"
+
+echo
+curl -sSf "https://cdn.mikrotik.com/routeros/$(echo "$packagename" | cut -d "-" -f 2)/CHANGELOG"
+echo
+echo
diff --git a/roles/routeros/files/mikrotik.mib b/roles/routeros/files/mikrotik.mib
new file mode 100644
index 0000000..d640b4a
--- /dev/null
+++ b/roles/routeros/files/mikrotik.mib
@@ -0,0 +1,4159 @@
+MIKROTIK-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+InetAddressType, InetAddress, InetPortNumber FROM INET-ADDRESS-MIB
+MODULE-IDENTITY, OBJECT-TYPE, Integer32, Counter32, Gauge32, IpAddress,
+Counter64, enterprises, NOTIFICATION-TYPE, TimeTicks FROM SNMPv2-SMI
+TEXTUAL-CONVENTION, DisplayString, MacAddress, TruthValue, DateAndTime FROM SNMPv2-TC
+OBJECT-GROUP, NOTIFICATION-GROUP FROM SNMPv2-CONF;
+
+mikrotikExperimentalModule MODULE-IDENTITY
+ LAST-UPDATED "202502050000Z"
+ ORGANIZATION "MikroTik"
+ CONTACT-INFO "support@mikrotik.com"
+ DESCRIPTION ""
+ REVISION "202502050000Z"
+ DESCRIPTION ""
+ ::= { mikrotik 1 }
+
+mikrotik OBJECT IDENTIFIER ::= { enterprises 14988 }
+mtXMetaInfo OBJECT IDENTIFIER ::= { mikrotikExperimentalModule 2 }
+mtXRouterOsGroups OBJECT IDENTIFIER ::= { mtXMetaInfo 1 }
+
+mtXRouterOs OBJECT IDENTIFIER ::= { mikrotikExperimentalModule 1 }
+mtxrWireless OBJECT IDENTIFIER ::= { mtXRouterOs 1 }
+mtxrQueues OBJECT IDENTIFIER ::= { mtXRouterOs 2 }
+mtxrHealth OBJECT IDENTIFIER ::= { mtXRouterOs 3 }
+mtxrLicense OBJECT IDENTIFIER ::= { mtXRouterOs 4 }
+mtxrHotspot OBJECT IDENTIFIER ::= { mtXRouterOs 5 }
+mtxrDHCP OBJECT IDENTIFIER ::= { mtXRouterOs 6 }
+mtxrSystem OBJECT IDENTIFIER ::= { mtXRouterOs 7 }
+mtxrScripts OBJECT IDENTIFIER ::= { mtXRouterOs 8 }
+mtxrTraps OBJECT IDENTIFIER ::= { mtXRouterOs 9 }
+mtxrNstremeDual OBJECT IDENTIFIER ::= { mtXRouterOs 10 }
+mtxrNeighbor OBJECT IDENTIFIER ::= { mtXRouterOs 11 }
+mtxrGps OBJECT IDENTIFIER ::= { mtXRouterOs 12 }
+mtxrWirelessModem OBJECT IDENTIFIER ::= { mtXRouterOs 13 }
+mtxrInterfaceStats OBJECT IDENTIFIER ::= { mtXRouterOs 14 }
+mtxrPOE OBJECT IDENTIFIER ::= { mtXRouterOs 15 }
+mtxrLTEModem OBJECT IDENTIFIER ::= { mtXRouterOs 16 }
+mtxrPartition OBJECT IDENTIFIER ::= { mtXRouterOs 17 }
+mtxrScriptRun OBJECT IDENTIFIER ::= { mtXRouterOs 18 }
+mtxrOptical OBJECT IDENTIFIER ::= { mtXRouterOs 19 }
+mtxrIPSec OBJECT IDENTIFIER ::= { mtXRouterOs 20 }
+mtxrWifi OBJECT IDENTIFIER ::= { mtXRouterOs 21 }
+
+ObjectIndex ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "x"
+ STATUS current
+ DESCRIPTION "Internal "
+ SYNTAX Integer32 (0..2147483647)
+-- Note that actually in RouterOs index values can be in range 0..4294967294,
+-- this can sometimes make them negative. Any of the following syntaxes would
+-- be more appropriate, but since Integer32 is used for InterfaceIndex in
+-- IF-MIB, where it can also take negative values in RouterOs, it is used
+-- here for consistency.
+-- Also note that ObjectIndex value is not related to item numbers that are
+-- used by console and shown by console print command.
+--
+-- SYNTAX Integer32 (-2147483648..2147483647)
+-- SYNTAX Unsigned32 (0..4294967295)
+
+HexInt ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "x"
+ STATUS current
+ DESCRIPTION "Hex"
+ SYNTAX Integer32 (-2147483648..2147483647)
+
+Voltage ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "d-1"
+ STATUS current
+ DESCRIPTION ""
+ SYNTAX Integer32 (-2147483648..2147483647)
+
+Temperature ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "d-1"
+ STATUS current
+ DESCRIPTION ""
+ SYNTAX Integer32 (-2147483648..2147483647)
+
+Power ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "d-1"
+ STATUS current
+ DESCRIPTION ""
+ SYNTAX Integer32 (-2147483648..2147483647)
+
+GDiv100 ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "d-2"
+ STATUS current
+ DESCRIPTION "/100"
+ SYNTAX Gauge32
+
+GDiv1000 ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "d-3"
+ STATUS current
+ DESCRIPTION "/1000"
+ SYNTAX Gauge32
+
+IDiv1000 ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "d-3"
+ STATUS current
+ DESCRIPTION "/1000"
+ SYNTAX Integer32 (-2147483648..2147483647)
+
+BoolValue ::= TEXTUAL-CONVENTION
+ STATUS current
+ DESCRIPTION
+ "Boolean value."
+ SYNTAX INTEGER { false(0), true(1) }
+
+IsakmpCookie ::= TEXTUAL-CONVENTION
+ DISPLAY-HINT "16a"
+ STATUS current
+ DESCRIPTION "ISAKMP cookie string"
+ SYNTAX OCTET STRING (SIZE (16))
+
+-- WIRELESS ********************************************************************
+
+mtxrWlStatTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWlStatEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 1 }
+
+mtxrWlStatEntry OBJECT-TYPE
+ SYNTAX MtxrWlStatEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Wireless station mode interface"
+ INDEX { mtxrWlStatIndex }
+ ::= { mtxrWlStatTable 1 }
+
+MtxrWlStatEntry ::= SEQUENCE {
+ mtxrWlStatIndex ObjectIndex,
+ mtxrWlStatTxRate Gauge32,
+ mtxrWlStatRxRate Gauge32,
+ mtxrWlStatStrength Integer32,
+ mtxrWlStatSsid DisplayString,
+ mtxrWlStatBssid MacAddress,
+ mtxrWlStatFreq Integer32,
+ mtxrWlStatBand DisplayString,
+ mtxrWlStatTxCCQ Counter32,
+ mtxrWlStatRxCCQ Counter32
+}
+
+mtxrWlStatIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlStatEntry 1 }
+
+mtxrWlStatTxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlStatEntry 2 }
+
+mtxrWlStatRxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlStatEntry 3 }
+
+mtxrWlStatStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dBm"
+ ::= { mtxrWlStatEntry 4 }
+
+mtxrWlStatSsid OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlStatEntry 5 }
+
+mtxrWlStatBssid OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlStatEntry 6 }
+
+mtxrWlStatFreq OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "megahertz"
+ ::= { mtxrWlStatEntry 7 }
+
+mtxrWlStatBand OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlStatEntry 8 }
+
+mtxrWlStatTxCCQ OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlStatEntry 9 }
+
+mtxrWlStatRxCCQ OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlStatEntry 10 }
+
+-- WlRtabTable
+mtxrWlRtabTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWlRtabEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 2 }
+
+mtxrWlRtabEntry OBJECT-TYPE
+ SYNTAX MtxrWlRtabEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Wireless registration table. It is indexed by remote
+ mac-address and local interface index"
+ INDEX { mtxrWlRtabAddr, mtxrWlRtabIface }
+ ::= { mtxrWlRtabTable 1 }
+
+MtxrWlRtabEntry ::= SEQUENCE {
+ mtxrWlRtabAddr MacAddress,
+ mtxrWlRtabIface ObjectIndex,
+ mtxrWlRtabStrength Integer32,
+ mtxrWlRtabTxBytes Counter32,
+ mtxrWlRtabRxBytes Counter32,
+ mtxrWlRtabTxPackets Counter32,
+ mtxrWlRtabRxPackets Counter32,
+ mtxrWlRtabTxRate Gauge32,
+ mtxrWlRtabRxRate Gauge32,
+ mtxrWlRtabRouterOSVersion DisplayString,
+ mtxrWlRtabUptime TimeTicks,
+ mtxrWlRtabSignalToNoise Integer32,
+ mtxrWlRtabTxStrengthCh0 Integer32,
+ mtxrWlRtabRxStrengthCh0 Integer32,
+ mtxrWlRtabTxStrengthCh1 Integer32,
+ mtxrWlRtabRxStrengthCh1 Integer32,
+ mtxrWlRtabTxStrengthCh2 Integer32,
+ mtxrWlRtabRxStrengthCh2 Integer32,
+ mtxrWlRtabTxStrength Integer32,
+ mtxrWlRtabRadioName DisplayString
+}
+
+mtxrWlRtabAddr OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 1 }
+
+mtxrWlRtabIface OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 2 }
+
+mtxrWlRtabStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dBm"
+ ::= { mtxrWlRtabEntry 3 }
+
+mtxrWlRtabTxBytes OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 4 }
+
+mtxrWlRtabRxBytes OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 5 }
+
+mtxrWlRtabTxPackets OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 6 }
+
+mtxrWlRtabRxPackets OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 7 }
+
+mtxrWlRtabTxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlRtabEntry 8 }
+
+mtxrWlRtabRxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlRtabEntry 9 }
+
+mtxrWlRtabRouterOSVersion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "RouterOS version"
+ ::= { mtxrWlRtabEntry 10 }
+
+mtxrWlRtabUptime OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "uptime"
+ ::= { mtxrWlRtabEntry 11 }
+
+mtxrWlRtabSignalToNoise OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Measured in dB, if value does not exist it is indicated with 0"
+ ::= { mtxrWlRtabEntry 12 }
+
+mtxrWlRtabTxStrengthCh0 OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 13 }
+
+mtxrWlRtabRxStrengthCh0 OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 14 }
+
+mtxrWlRtabTxStrengthCh1 OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 15 }
+
+mtxrWlRtabRxStrengthCh1 OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 16 }
+
+mtxrWlRtabTxStrengthCh2 OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 17 }
+
+mtxrWlRtabRxStrengthCh2 OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 18 }
+
+mtxrWlRtabTxStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 19 }
+
+mtxrWlRtabRadioName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlRtabEntry 20 }
+
+mtxrWlRtabEntryCount OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Wireless registration table entry count"
+ ::= { mtxrWireless 4 }
+
+mtxrWlApTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWlApEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 3 }
+
+mtxrWlApEntry OBJECT-TYPE
+ SYNTAX MtxrWlApEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Wireless access point mode interface"
+ INDEX { mtxrWlApIndex }
+ ::= { mtxrWlApTable 1 }
+
+MtxrWlApEntry ::= SEQUENCE {
+ mtxrWlApIndex ObjectIndex,
+ mtxrWlApTxRate Gauge32,
+ mtxrWlApRxRate Gauge32,
+ mtxrWlApSsid DisplayString,
+ mtxrWlApBssid MacAddress,
+ mtxrWlApClientCount Counter32,
+ mtxrWlApFreq Integer32,
+ mtxrWlApBand DisplayString,
+ mtxrWlApNoiseFloor Integer32,
+ mtxrWlApOverallTxCCQ Counter32,
+ mtxrWlApAuthClientCount Counter32
+}
+
+mtxrWlApIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 1 }
+
+mtxrWlApTxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlApEntry 2 }
+
+mtxrWlApRxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlApEntry 3 }
+
+mtxrWlApSsid OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 4 }
+
+mtxrWlApBssid OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 5 }
+
+mtxrWlApClientCount OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 6 }
+
+mtxrWlApFreq OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "megahertz"
+ ::= { mtxrWlApEntry 7 }
+
+mtxrWlApBand OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 8 }
+
+mtxrWlApNoiseFloor OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 9 }
+
+mtxrWlApOverallTxCCQ OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 10 }
+
+mtxrWlApAuthClientCount OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlApEntry 11 }
+
+mtxrWlCMRtabTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWlCMRtabEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 5 }
+
+mtxrWlCMRtabEntry OBJECT-TYPE
+ SYNTAX MtxrWlCMRtabEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Wireless CAPSMAN registration table. It is indexed by remote
+ mac-address and local interface index"
+ INDEX { mtxrWlCMRtabAddr, mtxrWlCMRtabIface }
+ ::= { mtxrWlCMRtabTable 1 }
+
+MtxrWlCMRtabEntry ::= SEQUENCE {
+ mtxrWlCMRtabAddr MacAddress,
+ mtxrWlCMRtabIface ObjectIndex,
+ mtxrWlCMRtabUptime TimeTicks,
+ mtxrWlCMRtabTxBytes Counter32,
+ mtxrWlCMRtabRxBytes Counter32,
+ mtxrWlCMRtabTxPackets Counter32,
+ mtxrWlCMRtabRxPackets Counter32,
+ mtxrWlCMRtabTxRate Gauge32,
+ mtxrWlCMRtabRxRate Gauge32,
+ mtxrWlCMRtabTxStrength Integer32,
+ mtxrWlCMRtabRxStrength Integer32,
+ mtxrWlCMRtabSsid DisplayString,
+ mtxrWlCMRtabEapIdent DisplayString
+}
+
+mtxrWlCMRtabAddr OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 1 }
+ -- should not be accessible in SMIv2
+
+mtxrWlCMRtabIface OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 2 }
+
+mtxrWlCMRtabUptime OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "uptime"
+ ::= { mtxrWlCMRtabEntry 3 }
+
+mtxrWlCMRtabTxBytes OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 4 }
+
+mtxrWlCMRtabRxBytes OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 5 }
+
+mtxrWlCMRtabTxPackets OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 6 }
+
+mtxrWlCMRtabRxPackets OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 7 }
+
+mtxrWlCMRtabTxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlCMRtabEntry 8 }
+
+mtxrWlCMRtabRxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrWlCMRtabEntry 9 }
+
+mtxrWlCMRtabTxStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 10 }
+
+mtxrWlCMRtabRxStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 11 }
+
+mtxrWlCMRtabSsid OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 12 }
+
+mtxrWlCMRtabEapIdent OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRtabEntry 13 }
+
+mtxrWlCMRtabEntryCount OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Wireless CAPSMAN registration table entry count"
+ ::= { mtxrWireless 6 }
+
+mtxrWlCMREntryCount OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Wireless CAPSMAN remote-cap entry count"
+ ::= { mtxrWireless 10 }
+
+mtxrWlCMTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWlCMEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 7 }
+
+mtxrWlCMEntry OBJECT-TYPE
+ SYNTAX MtxrWlCMEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "CAPS-MAN mode interface"
+ INDEX { mtxrWlCMIndex }
+ ::= { mtxrWlCMTable 1 }
+
+MtxrWlCMEntry ::= SEQUENCE {
+ mtxrWlCMIndex ObjectIndex,
+ mtxrWlCMRegClientCount Counter32,
+ mtxrWlCMAuthClientCount Counter32,
+ mtxrWlCMState DisplayString,
+ mtxrWlCMChannel DisplayString
+}
+
+mtxrWlCMIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMEntry 1 }
+
+mtxrWlCMRegClientCount OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMEntry 2 }
+
+mtxrWlCMAuthClientCount OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMEntry 3 }
+
+mtxrWlCMState OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMEntry 4 }
+
+mtxrWlCMChannel OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "for master only"
+ ::= { mtxrWlCMEntry 5 }
+
+--
+mtxrWlCMRemoteTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWlCMRemoteEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 11 }
+
+mtxrWlCMRemoteEntry OBJECT-TYPE
+ SYNTAX MtxrWlCMRemoteEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "CAPSMAN remote-cap list"
+ INDEX { mtxrWlCMRemoteIndex }
+ ::= { mtxrWlCMRemoteTable 1 }
+
+MtxrWlCMRemoteEntry ::= SEQUENCE {
+ mtxrWlCMRemoteIndex ObjectIndex,
+ mtxrWlCMRemoteName DisplayString,
+ mtxrWlCMRemoteState DisplayString,
+ mtxrWlCMRemoteAddress DisplayString,
+ mtxrWlCMRemoteRadios Counter32
+}
+
+mtxrWlCMRemoteIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRemoteEntry 1 }
+
+mtxrWlCMRemoteName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRemoteEntry 2 }
+
+mtxrWlCMRemoteState OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRemoteEntry 3 }
+
+mtxrWlCMRemoteAddress OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRemoteEntry 4 }
+
+mtxrWlCMRemoteRadios OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWlCMRemoteEntry 5 }
+
+-- W60G
+mtxrWl60GTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWl60GEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 8 }
+
+mtxrWl60GEntry OBJECT-TYPE
+ SYNTAX MtxrWl60GEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "W60G interface"
+ INDEX { mtxrWl60GIndex }
+ ::= { mtxrWl60GTable 1 }
+
+MtxrWl60GEntry ::= SEQUENCE {
+ mtxrWl60GIndex ObjectIndex,
+ mtxrWl60GMode INTEGER,
+ mtxrWl60GSsid DisplayString,
+ mtxrWl60GConnected BoolValue,
+ mtxrWl60GRemote MacAddress,
+ mtxrWl60GFreq Integer32,
+ mtxrWl60GMcs Integer32,
+ mtxrWl60GSignal Integer32,
+ mtxrWl60GTxSector Integer32,
+ mtxrWl60GTxSectorInfo DisplayString,
+ mtxrWl60GRssi Integer32,
+ mtxrWl60GPhyRate Gauge32
+}
+
+mtxrWl60GIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 1 }
+
+mtxrWl60GMode OBJECT-TYPE
+ SYNTAX INTEGER {
+ apBridge(0),
+ stationBridge(1),
+ sniff(2),
+ bridge(3)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 2 }
+
+mtxrWl60GSsid OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 3 }
+
+mtxrWl60GConnected OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 4 }
+
+mtxrWl60GRemote OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 5 }
+
+mtxrWl60GFreq OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Mhz"
+ ::= { mtxrWl60GEntry 6 }
+
+mtxrWl60GMcs OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 7 }
+
+mtxrWl60GSignal OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 8 }
+
+mtxrWl60GTxSector OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 9 }
+
+mtxrWl60GTxSectorInfo OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 11 }
+
+mtxrWl60GRssi OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 12 }
+
+mtxrWl60GPhyRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GEntry 13 }
+
+-- W60GSta
+mtxrWl60GStaTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWl60GStaEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWireless 9 }
+
+mtxrWl60GStaEntry OBJECT-TYPE
+ SYNTAX MtxrWl60GStaEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "W60G stations"
+ INDEX { mtxrWl60GStaIndex }
+ ::= { mtxrWl60GStaTable 1 }
+
+MtxrWl60GStaEntry ::= SEQUENCE {
+ mtxrWl60GStaIndex ObjectIndex,
+ mtxrWl60GStaConnected BoolValue,
+ mtxrWl60GStaRemote MacAddress,
+ mtxrWl60GStaMcs Integer32,
+ mtxrWl60GStaSignal Integer32,
+ mtxrWl60GStaTxSector Integer32,
+ mtxrWl60GStaPhyRate Gauge32,
+ mtxrWl60GStaRssi Integer32,
+ mtxrWl60GStaDistance Integer32
+}
+
+mtxrWl60GStaIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GStaEntry 1 }
+
+mtxrWl60GStaConnected OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GStaEntry 2 }
+
+mtxrWl60GStaRemote OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GStaEntry 3 }
+
+mtxrWl60GStaMcs OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GStaEntry 4 }
+
+mtxrWl60GStaSignal OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GStaEntry 5 }
+
+mtxrWl60GStaTxSector OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GStaEntry 6 }
+
+mtxrWl60GStaPhyRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Mbits per second"
+ ::= { mtxrWl60GStaEntry 8 }
+
+mtxrWl60GStaRssi OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWl60GStaEntry 9 }
+
+mtxrWl60GStaDistance OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "meters"
+ ::= { mtxrWl60GStaEntry 10 }
+
+
+mtxrWirelessGroup OBJECT-GROUP OBJECTS {
+ mtxrWlStatTxRate,
+ mtxrWlStatRxRate,
+ mtxrWlStatStrength,
+ mtxrWlStatSsid,
+ mtxrWlStatBssid,
+ mtxrWlStatFreq,
+ mtxrWlStatBand,
+ mtxrWlStatTxCCQ,
+ mtxrWlStatRxCCQ,
+ mtxrWlRtabStrength,
+ mtxrWlRtabTxBytes,
+ mtxrWlRtabRxBytes,
+ mtxrWlRtabTxPackets,
+ mtxrWlRtabRxPackets,
+ mtxrWlRtabTxRate,
+ mtxrWlRtabRxRate,
+ mtxrWlRtabEntryCount,
+ mtxrWlRtabRouterOSVersion,
+ mtxrWlRtabUptime,
+ mtxrWlRtabSignalToNoise,
+ mtxrWlRtabTxStrengthCh0,
+ mtxrWlRtabRxStrengthCh0,
+ mtxrWlRtabTxStrengthCh1,
+ mtxrWlRtabRxStrengthCh1,
+ mtxrWlRtabTxStrengthCh2,
+ mtxrWlRtabRxStrengthCh2,
+ mtxrWlRtabTxStrength,
+ mtxrWlRtabRadioName,
+ mtxrWlApTxRate,
+ mtxrWlApRxRate,
+ mtxrWlApSsid,
+ mtxrWlApBssid,
+ mtxrWlApClientCount,
+ mtxrWlApBand,
+ mtxrWlApFreq,
+ mtxrWlApNoiseFloor,
+ mtxrWlApOverallTxCCQ,
+ mtxrWlApAuthClientCount,
+ mtxrWlCMRtabAddr,
+ mtxrWlCMRtabTxBytes,
+ mtxrWlCMRtabRxBytes,
+ mtxrWlCMRtabTxPackets,
+ mtxrWlCMRtabRxPackets,
+ mtxrWlCMRtabTxRate,
+ mtxrWlCMRtabRxRate,
+ mtxrWlCMRtabUptime,
+ mtxrWlCMRtabTxStrength,
+ mtxrWlCMRtabRxStrength,
+ mtxrWlCMRtabSsid,
+ mtxrWlCMRtabEntryCount,
+ mtxrWlCMREntryCount,
+ mtxrWlCMRegClientCount,
+ mtxrWlCMAuthClientCount,
+ mtxrWl60GMode,
+ mtxrWl60GSsid,
+ mtxrWl60GConnected,
+ mtxrWl60GRemote,
+ mtxrWl60GFreq,
+ mtxrWl60GMcs,
+ mtxrWl60GSignal,
+ mtxrWl60GTxSector,
+ mtxrWl60GTxSectorInfo,
+ mtxrWl60GRssi,
+ mtxrWl60GPhyRate,
+ mtxrWl60GStaConnected,
+ mtxrWl60GStaRemote,
+ mtxrWl60GStaMcs,
+ mtxrWl60GStaSignal,
+ mtxrWl60GStaTxSector
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 1 }
+
+-- QUEUES ********************************************************************
+
+mtxrQueueSimpleTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrQueueSimpleEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueues 1 }
+
+mtxrQueueSimpleEntry OBJECT-TYPE
+ SYNTAX MtxrQueueSimpleEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Simple queue"
+ INDEX { mtxrQueueSimpleIndex }
+ ::= { mtxrQueueSimpleTable 1 }
+
+MtxrQueueSimpleEntry ::= SEQUENCE {
+ mtxrQueueSimpleIndex ObjectIndex,
+ mtxrQueueSimpleName DisplayString,
+ mtxrQueueSimpleSrcAddr IpAddress,
+ mtxrQueueSimpleSrcMask IpAddress,
+ mtxrQueueSimpleDstAddr IpAddress,
+ mtxrQueueSimpleDstMask IpAddress,
+ mtxrQueueSimpleIface ObjectIndex,
+ mtxrQueueSimpleBytesIn Counter64,
+ mtxrQueueSimpleBytesOut Counter64,
+ mtxrQueueSimplePacketsIn Counter32,
+ mtxrQueueSimplePacketsOut Counter32,
+ mtxrQueueSimplePCQQueuesIn Counter32,
+ mtxrQueueSimplePCQQueuesOut Counter32,
+ mtxrQueueSimpleDroppedIn Counter32,
+ mtxrQueueSimpleDroppedOut Counter32
+}
+
+mtxrQueueSimpleIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 1 }
+
+mtxrQueueSimpleName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 2 }
+
+mtxrQueueSimpleSrcAddr OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 3 }
+
+mtxrQueueSimpleSrcMask OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 4 }
+
+mtxrQueueSimpleDstAddr OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 5 }
+
+mtxrQueueSimpleDstMask OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 6 }
+
+mtxrQueueSimpleIface OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "interface index"
+ ::= { mtxrQueueSimpleEntry 7 }
+
+mtxrQueueSimpleBytesIn OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 8 }
+
+mtxrQueueSimpleBytesOut OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 9 }
+
+mtxrQueueSimplePacketsIn OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 10 }
+
+mtxrQueueSimplePacketsOut OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 11 }
+
+mtxrQueueSimplePCQQueuesIn OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 12 }
+
+mtxrQueueSimplePCQQueuesOut OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 13 }
+
+mtxrQueueSimpleDroppedIn OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 14 }
+
+mtxrQueueSimpleDroppedOut OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueSimpleEntry 15 }
+
+mtxrQueueTreeTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrQueueTreeEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueues 2 }
+
+mtxrQueueTreeEntry OBJECT-TYPE
+ SYNTAX MtxrQueueTreeEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Tree queue"
+ INDEX { mtxrQueueTreeIndex }
+ ::= { mtxrQueueTreeTable 1 }
+
+MtxrQueueTreeEntry ::= SEQUENCE {
+ mtxrQueueTreeIndex ObjectIndex,
+ mtxrQueueTreeName DisplayString,
+ mtxrQueueTreeFlow DisplayString,
+ mtxrQueueTreeParentIndex ObjectIndex,
+ mtxrQueueTreeBytes Counter32,
+ mtxrQueueTreePackets Counter32,
+ mtxrQueueTreeHCBytes Counter64,
+ mtxrQueueTreePCQQueues Counter32,
+ mtxrQueueTreeDropped Counter32
+}
+
+mtxrQueueTreeIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueTreeEntry 1 }
+
+mtxrQueueTreeName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueTreeEntry 2 }
+
+mtxrQueueTreeFlow OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "flowmark"
+ ::= { mtxrQueueTreeEntry 3 }
+
+mtxrQueueTreeParentIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "index of parent tree queue or parent interface"
+ ::= { mtxrQueueTreeEntry 4 }
+
+mtxrQueueTreeBytes OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueTreeEntry 5 }
+
+mtxrQueueTreePackets OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueTreeEntry 6 }
+
+mtxrQueueTreeHCBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueTreeEntry 7 }
+
+mtxrQueueTreePCQQueues OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueTreeEntry 8 }
+
+mtxrQueueTreeDropped OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrQueueTreeEntry 9 }
+
+mtxrQueueGroup OBJECT-GROUP OBJECTS {
+ mtxrQueueSimpleName, mtxrQueueSimpleSrcAddr, mtxrQueueSimpleSrcMask,
+ mtxrQueueSimpleDstAddr, mtxrQueueSimpleDstMask, mtxrQueueSimpleIface,
+ mtxrQueueSimpleBytesIn, mtxrQueueSimpleBytesOut,
+ mtxrQueueSimplePacketsIn, mtxrQueueSimplePacketsOut, mtxrQueueTreeName,
+ mtxrQueueSimplePCQQueuesIn,
+ mtxrQueueSimplePCQQueuesOut,
+ mtxrQueueSimpleDroppedIn,
+ mtxrQueueSimpleDroppedOut,
+ mtxrQueueTreeFlow, mtxrQueueTreeParentIndex, mtxrQueueTreeBytes,
+ mtxrQueueTreePackets,
+ mtxrQueueTreeHCBytes,
+ mtxrQueueTreePCQQueues,
+ mtxrQueueTreeDropped
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 2 }
+
+-- HEALTH ********************************************************************
+
+mtxrHlCoreVoltage OBJECT-TYPE
+ SYNTAX Voltage
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "core voltage"
+ ::= { mtxrHealth 1 }
+
+mtxrHlThreeDotThreeVoltage OBJECT-TYPE
+ SYNTAX Voltage
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "3.3V voltage"
+ ::= { mtxrHealth 2 }
+
+mtxrHlFiveVoltage OBJECT-TYPE
+ SYNTAX Voltage
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "5V voltage"
+ ::= { mtxrHealth 3 }
+
+mtxrHlTwelveVoltage OBJECT-TYPE
+ SYNTAX Voltage
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "12V voltage"
+ ::= { mtxrHealth 4 }
+
+mtxrHlSensorTemperature OBJECT-TYPE
+ SYNTAX Temperature
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "temperature at sensor chip"
+ ::= { mtxrHealth 5 }
+
+mtxrHlCpuTemperature OBJECT-TYPE
+ SYNTAX Temperature
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "temperature near cpu"
+ ::= { mtxrHealth 6 }
+
+mtxrHlBoardTemperature OBJECT-TYPE
+ SYNTAX Temperature
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHealth 7 }
+
+mtxrHlVoltage OBJECT-TYPE
+ SYNTAX Voltage
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHealth 8 }
+
+mtxrHlActiveFan OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHealth 9 }
+
+mtxrHlTemperature OBJECT-TYPE
+ SYNTAX Temperature
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHealth 10 }
+
+mtxrHlProcessorTemperature OBJECT-TYPE
+ SYNTAX Temperature
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHealth 11 }
+
+mtxrHlPower OBJECT-TYPE
+ SYNTAX Power
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Watts"
+ ::= { mtxrHealth 12 }
+
+mtxrHlCurrent OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "mA"
+ ::= { mtxrHealth 13 }
+
+mtxrHlProcessorFrequency OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Mhz"
+ ::= { mtxrHealth 14 }
+
+mtxrHlPowerSupplyState OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "PSU state ok"
+ ::= { mtxrHealth 15 }
+
+mtxrHlBackupPowerSupplyState OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "backup PSU state ok"
+ ::= { mtxrHealth 16 }
+
+mtxrHlFanSpeed1 OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "rpm"
+ ::= { mtxrHealth 17 }
+
+mtxrHlFanSpeed2 OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "rpm"
+ ::= { mtxrHealth 18 }
+
+mtxrAlarmSocketStatus OBJECT-TYPE
+ SYNTAX INTEGER {
+ inactive(0),
+ active(1)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Alarm socket status"
+ ::= { mtxrHealth 19 }
+
+mtxrGaugeTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrGaugeTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHealth 100 }
+
+mtxrGaugeTableEntry OBJECT-TYPE
+ SYNTAX MtxrGaugeTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrGaugeIndex }
+ ::= { mtxrGaugeTable 1 }
+
+MtxrGaugeTableEntry ::= SEQUENCE {
+ mtxrGaugeIndex ObjectIndex,
+ mtxrGaugeName DisplayString,
+ mtxrGaugeValue Integer32,
+ mtxrGaugeUnit INTEGER
+}
+
+mtxrGaugeIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrGaugeTableEntry 1 }
+
+mtxrGaugeName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrGaugeTableEntry 2 }
+
+mtxrGaugeValue OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrGaugeTableEntry 3 }
+
+mtxrGaugeUnit OBJECT-TYPE
+ SYNTAX INTEGER {
+ celsius(1),
+ rpm(2),
+ dV(3),
+ dA(4),
+ dW(5),
+ status(6)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "units"
+ ::= { mtxrGaugeTableEntry 4 }
+
+mtxrHealthGroup OBJECT-GROUP OBJECTS {
+ mtxrHlCoreVoltage, mtxrHlThreeDotThreeVoltage, mtxrHlFiveVoltage,
+ mtxrHlTwelveVoltage, mtxrHlSensorTemperature, mtxrHlCpuTemperature,
+ mtxrHlBoardTemperature, mtxrHlVoltage, mtxrHlActiveFan,
+ mtxrHlTemperature, mtxrHlProcessorTemperature,
+ mtxrHlCurrent, mtxrHlPower,
+ mtxrHlProcessorFrequency,
+ mtxrHlPowerSupplyState, mtxrHlBackupPowerSupplyState,
+ mtxrHlFanSpeed1, mtxrHlFanSpeed2, mtxrAlarmSocketStatus,
+ mtxrGaugeName, mtxrGaugeValue, mtxrGaugeUnit
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 3 }
+
+-- LICENSE ********************************************************************
+
+mtxrLicSoftwareId OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "software id"
+ ::= { mtxrLicense 1 }
+
+mtxrLicUpgrUntil OBJECT-TYPE
+ SYNTAX DateAndTime
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "current key allows upgrading until this date"
+ ::= { mtxrLicense 2 }
+
+mtxrLicLevel OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "current key level"
+ ::= { mtxrLicense 3 }
+
+mtxrLicVersion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "software version"
+ ::= { mtxrLicense 4 }
+
+mtxrLicUpgradableTo OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "upgradable to"
+ ::= { mtxrLicense 5 }
+
+mtxrLincenseGroup OBJECT-GROUP OBJECTS {
+ mtxrLicSoftwareId, mtxrLicUpgrUntil, mtxrLicLevel, mtxrLicVersion, mtxrLicUpgradableTo
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 4 }
+
+-- HOTSPOT ***************************************************************
+
+mtxrHotspotActiveUsersTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrHotspotActiveUsersTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspot 1 }
+
+mtxrHotspotActiveUsersTableEntry OBJECT-TYPE
+ SYNTAX MtxrHotspotActiveUsersTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrHotspotActiveUserIndex }
+ ::= { mtxrHotspotActiveUsersTable 1 }
+
+MtxrHotspotActiveUsersTableEntry ::= SEQUENCE {
+ mtxrHotspotActiveUserIndex ObjectIndex,
+ mtxrHotspotActiveUserServerID Integer32,
+ mtxrHotspotActiveUserName DisplayString,
+ mtxrHotspotActiveUserDomain DisplayString,
+ mtxrHotspotActiveUserIP IpAddress,
+ mtxrHotspotActiveUserMAC MacAddress,
+ mtxrHotspotActiveUserConnectTime Integer32,
+ mtxrHotspotActiveUserValidTillTime Integer32,
+ mtxrHotspotActiveUserIdleStartTime Integer32,
+ mtxrHotspotActiveUserIdleTimeout Integer32,
+ mtxrHotspotActiveUserPingTimeout Integer32,
+ mtxrHotspotActiveUserBytesIn Counter64,
+ mtxrHotspotActiveUserBytesOut Counter64,
+ mtxrHotspotActiveUserPacketsIn Counter64,
+ mtxrHotspotActiveUserPacketsOut Counter64,
+ mtxrHotspotActiveUserLimitBytesIn Counter64,
+ mtxrHotspotActiveUserLimitBytesOut Counter64,
+ mtxrHotspotActiveUserAdvertStatus Integer32,
+ mtxrHotspotActiveUserRadius Integer32,
+ mtxrHotspotActiveUserBlockedByAdvert Integer32
+}
+
+mtxrHotspotActiveUserIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 1 }
+
+mtxrHotspotActiveUserServerID OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 2 }
+
+mtxrHotspotActiveUserName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 3 }
+
+mtxrHotspotActiveUserDomain OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 4 }
+
+mtxrHotspotActiveUserIP OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 5 }
+
+mtxrHotspotActiveUserMAC OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 6 }
+
+mtxrHotspotActiveUserConnectTime OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 7 }
+
+mtxrHotspotActiveUserValidTillTime OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 8 }
+
+mtxrHotspotActiveUserIdleStartTime OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 9 }
+
+mtxrHotspotActiveUserIdleTimeout OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 10 }
+
+mtxrHotspotActiveUserPingTimeout OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 11 }
+
+mtxrHotspotActiveUserBytesIn OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 12 }
+
+mtxrHotspotActiveUserBytesOut OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 13 }
+
+mtxrHotspotActiveUserPacketsIn OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 14 }
+
+mtxrHotspotActiveUserPacketsOut OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 15 }
+
+mtxrHotspotActiveUserLimitBytesIn OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 16 }
+
+mtxrHotspotActiveUserLimitBytesOut OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 17 }
+
+mtxrHotspotActiveUserAdvertStatus OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 18 }
+
+mtxrHotspotActiveUserRadius OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 19 }
+
+mtxrHotspotActiveUserBlockedByAdvert OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrHotspotActiveUsersTableEntry 20 }
+
+mtxrHotspotActiveUserGroup OBJECT-GROUP OBJECTS {
+ mtxrHotspotActiveUserServerID,
+ mtxrHotspotActiveUserName,
+ mtxrHotspotActiveUserDomain,
+ mtxrHotspotActiveUserIP,
+ mtxrHotspotActiveUserMAC,
+ mtxrHotspotActiveUserConnectTime,
+ mtxrHotspotActiveUserValidTillTime,
+ mtxrHotspotActiveUserIdleStartTime,
+ mtxrHotspotActiveUserIdleTimeout,
+ mtxrHotspotActiveUserPingTimeout,
+ mtxrHotspotActiveUserBytesIn,
+ mtxrHotspotActiveUserBytesOut,
+ mtxrHotspotActiveUserPacketsIn,
+ mtxrHotspotActiveUserPacketsOut,
+ mtxrHotspotActiveUserLimitBytesIn,
+ mtxrHotspotActiveUserLimitBytesOut,
+ mtxrHotspotActiveUserAdvertStatus,
+ mtxrHotspotActiveUserRadius,
+ mtxrHotspotActiveUserBlockedByAdvert
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 5 }
+
+-- DHCP ********************************************************************
+
+mtxrDHCPLeaseCount OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrDHCP 1 }
+
+mtxrDHCPGroup OBJECT-GROUP OBJECTS {
+ mtxrDHCPLeaseCount
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 12 }
+
+-- SYSTEM ********************************************************************
+
+mtxrSystemReboot OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION "set non zero to reboot"
+ ::= { mtxrSystem 1 }
+
+mtxrUSBPowerReset OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION "switches off usb power for specified amout of seconds"
+ ::= { mtxrSystem 2 }
+
+mtxrSerialNumber OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "RouterBOARD serial number"
+ ::= { mtxrSystem 3 }
+
+mtxrFirmwareVersion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Current firmware version"
+ ::= { mtxrSystem 4 }
+
+mtxrNote OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "note"
+ ::= { mtxrSystem 5 }
+
+mtxrBuildTime OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "build time"
+ ::= { mtxrSystem 6 }
+
+mtxrFirmwareUpgradeVersion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Upgrade firmware version"
+ ::= { mtxrSystem 7 }
+
+mtxrDisplayName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "display name"
+ ::= { mtxrSystem 8 }
+
+mtxrBoardName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "board name"
+ ::= { mtxrSystem 9 }
+
+mtxrSystemGroup OBJECT-GROUP OBJECTS {
+ mtxrSystemReboot,
+ mtxrUSBPowerReset,
+ mtxrSerialNumber,
+ mtxrFirmwareVersion,
+ mtxrNote,
+ mtxrBuildTime,
+ mtxrFirmwareUpgradeVersion,
+ mtxrBoardName
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 13 }
+
+-- SCRIPTS ********************************************************************
+
+mtxrScriptTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrScriptTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrScripts 1 }
+
+mtxrScriptTableEntry OBJECT-TYPE
+ SYNTAX MtxrScriptTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrScriptIndex }
+ ::= { mtxrScriptTable 1 }
+
+MtxrScriptTableEntry ::= SEQUENCE {
+ mtxrScriptIndex ObjectIndex,
+ mtxrScriptName DisplayString,
+ mtxrScriptRunCmd Integer32
+}
+
+mtxrScriptIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrScriptTableEntry 1 }
+
+mtxrScriptName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrScriptTableEntry 2 }
+
+mtxrScriptRunCmd OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION "set non zero to run"
+ ::= { mtxrScriptTableEntry 3 }
+
+mtxrScriptGroup OBJECT-GROUP OBJECTS {
+ mtxrScriptName, mtxrScriptRunCmd
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 8 }
+
+-- SCRIPT RUN *****************************************************************
+
+mtxrScriptRunTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrScriptRunTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "invisible to getnext, accesible only with get request and write premission"
+ ::= { mtxrScriptRun 1 }
+
+mtxrScriptRunTableEntry OBJECT-TYPE
+ SYNTAX MtxrScriptRunTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrScriptRunIndex }
+ ::= { mtxrScriptRunTable 1 }
+
+MtxrScriptRunTableEntry ::= SEQUENCE {
+ mtxrScriptRunIndex ObjectIndex,
+ mtxrScriptRunOutput DisplayString
+}
+
+mtxrScriptRunIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrScriptRunTableEntry 1 }
+
+mtxrScriptRunOutput OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "this oid on get request will run script and return it's output"
+ ::= { mtxrScriptRunTableEntry 2 }
+
+mtxrScriptRunGroup OBJECT-GROUP OBJECTS {
+ mtxrScriptRunOutput
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 21 }
+
+-- Dual Nstreme ***************************************************************
+
+mtxrDnStatTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrDnStatEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNstremeDual 1 }
+
+mtxrDnStatEntry OBJECT-TYPE
+ SYNTAX MtxrDnStatEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Nstreme Dual interface"
+ INDEX { mtxrDnStatIndex }
+ ::= { mtxrDnStatTable 1 }
+
+MtxrDnStatEntry ::= SEQUENCE {
+ mtxrDnStatIndex ObjectIndex,
+ mtxrDnStatTxRate Gauge32,
+ mtxrDnStatRxRate Gauge32,
+ mtxrDnStatTxStrength Integer32,
+ mtxrDnStatRxStrength Integer32,
+ mtxrDnConnected Integer32
+}
+
+mtxrDnStatIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrDnStatEntry 1 }
+
+mtxrDnStatTxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrDnStatEntry 2 }
+
+mtxrDnStatRxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "bits per second"
+ ::= { mtxrDnStatEntry 3 }
+
+mtxrDnStatTxStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dBm"
+ ::= { mtxrDnStatEntry 4 }
+
+mtxrDnStatRxStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dBm"
+ ::= { mtxrDnStatEntry 5 }
+
+mtxrDnConnected OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "0 - not connected, connected otherwise"
+ ::= { mtxrDnStatEntry 6 }
+
+mtxrNstremeDualGroup OBJECT-GROUP OBJECTS {
+ mtxrDnStatTxRate, mtxrDnStatRxRate,
+ mtxrDnStatTxStrength, mtxrDnStatRxStrength, mtxrDnConnected
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 10 }
+
+-- NEIGHBOR *******************************************************************
+
+mtxrNeighborTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrNeighborTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighbor 1 }
+
+mtxrNeighborTableEntry OBJECT-TYPE
+ SYNTAX MtxrNeighborTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrNeighborIndex }
+ ::= { mtxrNeighborTable 1 }
+
+MtxrNeighborTableEntry ::= SEQUENCE {
+ mtxrNeighborIndex ObjectIndex,
+ mtxrNeighborIpAddress IpAddress,
+ mtxrNeighborMacAddress MacAddress,
+ mtxrNeighborVersion DisplayString,
+ mtxrNeighborPlatform DisplayString,
+ mtxrNeighborIdentity DisplayString,
+ mtxrNeighborSoftwareID DisplayString,
+ mtxrNeighborInterfaceID ObjectIndex
+}
+
+mtxrNeighborIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 1 }
+
+mtxrNeighborIpAddress OBJECT-TYPE
+ SYNTAX IpAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 2 }
+
+mtxrNeighborMacAddress OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 3 }
+
+mtxrNeighborVersion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 4 }
+
+mtxrNeighborPlatform OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 5 }
+
+mtxrNeighborIdentity OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 6 }
+
+mtxrNeighborSoftwareID OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 7 }
+
+mtxrNeighborInterfaceID OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrNeighborTableEntry 8 }
+
+mtxrNeighborGroup OBJECT-GROUP OBJECTS {
+ mtxrNeighborIpAddress,
+ mtxrNeighborMacAddress,
+ mtxrNeighborVersion,
+ mtxrNeighborPlatform,
+ mtxrNeighborIdentity,
+ mtxrNeighborSoftwareID,
+ mtxrNeighborInterfaceID
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 11 }
+
+-- GPS ************************************************************************
+
+mtxrDate OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "UNIX time"
+ ::= { mtxrGps 1 }
+
+mtxrLongtitude OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "longtitude"
+ ::= { mtxrGps 2 }
+
+mtxrLatitude OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "latitude"
+ ::= { mtxrGps 3 }
+
+mtxrAltitude OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "altitude"
+ ::= { mtxrGps 4 }
+
+mtxrSpeed OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "speed"
+ ::= { mtxrGps 5 }
+
+mtxrSattelites OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "visible sattelite count"
+ ::= { mtxrGps 6 }
+
+mtxrValid OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "is the data valid"
+ ::= { mtxrGps 7 }
+
+mtxrGPSGroup OBJECT-GROUP OBJECTS {
+ mtxrDate,
+ mtxrLongtitude,
+ mtxrLatitude,
+ mtxrAltitude,
+ mtxrSpeed,
+ mtxrSattelites,
+ mtxrValid
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 15 }
+
+-- Wireless Modem ************************************************************
+
+mtxrWirelessModemSignalStrength OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "signal strength in dBm (if first ppp-client modem supports)"
+ ::= { mtxrWirelessModem 1 }
+
+mtxrWirelessModemSignalECIO OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "signal EC/IO in dB (if first ppp-client modem supports)"
+ ::= { mtxrWirelessModem 2 }
+
+mtxrWirelessModemManufacturer OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Modem manufacturer name"
+ ::= { mtxrWirelessModem 3 }
+
+mtxrWirelessModemModel OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Modem model name"
+ ::= { mtxrWirelessModem 4 }
+
+mtxrWirelessModemRevision OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Modem firmware revision"
+ ::= { mtxrWirelessModem 5 }
+
+mtxrWirelessModemIMEI OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Modem serial number"
+ ::= { mtxrWirelessModem 6 }
+
+mtxrWirelessModemIMSI OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "International mobile subscriber identity"
+ ::= { mtxrWirelessModem 7 }
+
+mtxrWirelessModemAccessTechnology OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Access technology"
+ ::= { mtxrWirelessModem 8 }
+
+mtxrWirelessModemFrameErrorRate OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Signal frame error rate"
+ ::= { mtxrWirelessModem 9 }
+
+mtxrWirelessModemRSRP OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Reference Signal Receive Power"
+ ::= { mtxrWirelessModem 10 }
+
+mtxrWirelessModemRSRQ OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Reference Signal Received Quality"
+ ::= { mtxrWirelessModem 11 }
+
+mtxrWirelessModemSINR OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Signal-to-Interference-plus-Noise Ratio"
+ ::= { mtxrWirelessModem 12 }
+
+mtxrWirelessModemGroup OBJECT-GROUP OBJECTS {
+ mtxrWirelessModemSignalStrength,
+ mtxrWirelessModemSignalECIO,
+ mtxrWirelessModemManufacturer,
+ mtxrWirelessModemModel,
+ mtxrWirelessModemRevision,
+ mtxrWirelessModemIMEI,
+ mtxrWirelessModemIMSI,
+ mtxrWirelessModemAccessTechnology,
+ mtxrWirelessModemFrameErrorRate,
+ mtxrWirelessModemRSRP,
+ mtxrWirelessModemRSRQ,
+ mtxrWirelessModemSINR
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 16 }
+
+-- Interface Stats ************************************************************
+
+mtxrInterfaceStatsTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrInterfaceStatsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Extended interface statistics.
+ Some interfaces may have only parts of this table
+ with unavailable values set to zero."
+ ::= { mtxrInterfaceStats 1 }
+
+mtxrInterfaceStatsEntry OBJECT-TYPE
+ SYNTAX MtxrInterfaceStatsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrInterfaceStatsIndex }
+ ::= { mtxrInterfaceStatsTable 1 }
+
+MtxrInterfaceStatsEntry ::= SEQUENCE {
+ mtxrInterfaceStatsIndex ObjectIndex,
+ mtxrInterfaceStatsName DisplayString,
+
+ mtxrInterfaceStatsDriverRxBytes Counter64,
+ mtxrInterfaceStatsDriverRxPackets Counter64,
+ mtxrInterfaceStatsDriverTxBytes Counter64,
+ mtxrInterfaceStatsDriverTxPackets Counter64,
+
+ mtxrInterfaceStatsTxRx64 Counter64,
+ mtxrInterfaceStatsTxRx65To127 Counter64,
+ mtxrInterfaceStatsTxRx128To255 Counter64,
+ mtxrInterfaceStatsTxRx256To511 Counter64,
+ mtxrInterfaceStatsTxRx512To1023 Counter64,
+ mtxrInterfaceStatsTxRx1024To1518 Counter64,
+ mtxrInterfaceStatsTxRx1519ToMax Counter64,
+
+ mtxrInterfaceStatsRxBytes Counter64,
+ mtxrInterfaceStatsRxPackets Counter64,
+ mtxrInterfaceStatsRxTooShort Counter64,
+ mtxrInterfaceStatsRx64 Counter64,
+ mtxrInterfaceStatsRx65To127 Counter64,
+ mtxrInterfaceStatsRx128To255 Counter64,
+ mtxrInterfaceStatsRx256To511 Counter64,
+ mtxrInterfaceStatsRx512To1023 Counter64,
+ mtxrInterfaceStatsRx1024To1518 Counter64,
+ mtxrInterfaceStatsRx1519ToMax Counter64,
+ mtxrInterfaceStatsRxTooLong Counter64,
+ mtxrInterfaceStatsRxBroadcast Counter64,
+ mtxrInterfaceStatsRxPause Counter64,
+ mtxrInterfaceStatsRxMulticast Counter64,
+ mtxrInterfaceStatsRxFCSError Counter64,
+ mtxrInterfaceStatsRxAlignError Counter64,
+ mtxrInterfaceStatsRxFragment Counter64,
+ mtxrInterfaceStatsRxOverflow Counter64,
+ mtxrInterfaceStatsRxControl Counter64,
+ mtxrInterfaceStatsRxUnknownOp Counter64,
+ mtxrInterfaceStatsRxLengthError Counter64,
+ mtxrInterfaceStatsRxCodeError Counter64,
+ mtxrInterfaceStatsRxCarrierError Counter64,
+ mtxrInterfaceStatsRxJabber Counter64,
+ mtxrInterfaceStatsRxDrop Counter64,
+
+ mtxrInterfaceStatsTxBytes Counter64,
+ mtxrInterfaceStatsTxPackets Counter64,
+ mtxrInterfaceStatsTxTooShort Counter64,
+ mtxrInterfaceStatsTx64 Counter64,
+ mtxrInterfaceStatsTx65To127 Counter64,
+ mtxrInterfaceStatsTx128To255 Counter64,
+ mtxrInterfaceStatsTx256To511 Counter64,
+ mtxrInterfaceStatsTx512To1023 Counter64,
+ mtxrInterfaceStatsTx1024To1518 Counter64,
+ mtxrInterfaceStatsTx1519ToMax Counter64,
+ mtxrInterfaceStatsTxTooLong Counter64,
+ mtxrInterfaceStatsTxBroadcast Counter64,
+ mtxrInterfaceStatsTxPause Counter64,
+ mtxrInterfaceStatsTxMulticast Counter64,
+ mtxrInterfaceStatsTxUnderrun Counter64,
+ mtxrInterfaceStatsTxCollision Counter64,
+ mtxrInterfaceStatsTxExcessiveCollision Counter64,
+ mtxrInterfaceStatsTxMultipleCollision Counter64,
+ mtxrInterfaceStatsTxSingleCollision Counter64,
+ mtxrInterfaceStatsTxExcessiveDeferred Counter64,
+ mtxrInterfaceStatsTxDeferred Counter64,
+ mtxrInterfaceStatsTxLateCollision Counter64,
+ mtxrInterfaceStatsTxTotalCollision Counter64,
+ mtxrInterfaceStatsTxPauseHonored Counter64,
+ mtxrInterfaceStatsTxDrop Counter64,
+ mtxrInterfaceStatsTxJabber Counter64,
+ mtxrInterfaceStatsTxFCSError Counter64,
+ mtxrInterfaceStatsTxControl Counter64,
+ mtxrInterfaceStatsTxFragment Counter64,
+ mtxrInterfaceStatsLinkDowns Counter32,
+ mtxrInterfaceStatsTxRx1024ToMax Counter64
+}
+
+mtxrInterfaceStatsIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 1 }
+
+mtxrInterfaceStatsName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 2 }
+
+mtxrInterfaceStatsDriverRxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 11 }
+
+mtxrInterfaceStatsDriverRxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 12 }
+
+mtxrInterfaceStatsDriverTxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 13 }
+
+mtxrInterfaceStatsDriverTxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 14 }
+
+mtxrInterfaceStatsTxRx64 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 15 }
+
+mtxrInterfaceStatsTxRx65To127 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 16 }
+
+mtxrInterfaceStatsTxRx128To255 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 17 }
+
+mtxrInterfaceStatsTxRx256To511 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 18 }
+
+mtxrInterfaceStatsTxRx512To1023 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 19 }
+
+mtxrInterfaceStatsTxRx1024To1518 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 20 }
+
+mtxrInterfaceStatsTxRx1519ToMax OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 21 }
+
+mtxrInterfaceStatsRxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 31 }
+
+mtxrInterfaceStatsRxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 32 }
+
+mtxrInterfaceStatsRxTooShort OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 33 }
+
+mtxrInterfaceStatsRx64 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 34 }
+
+mtxrInterfaceStatsRx65To127 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 35 }
+
+mtxrInterfaceStatsRx128To255 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 36 }
+
+mtxrInterfaceStatsRx256To511 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 37 }
+
+mtxrInterfaceStatsRx512To1023 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 38 }
+
+mtxrInterfaceStatsRx1024To1518 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 39 }
+
+mtxrInterfaceStatsRx1519ToMax OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 40 }
+
+mtxrInterfaceStatsRxTooLong OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 41 }
+
+mtxrInterfaceStatsRxBroadcast OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 42 }
+
+mtxrInterfaceStatsRxPause OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 43 }
+
+mtxrInterfaceStatsRxMulticast OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 44 }
+
+mtxrInterfaceStatsRxFCSError OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 45 }
+
+mtxrInterfaceStatsRxAlignError OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 46 }
+
+mtxrInterfaceStatsRxFragment OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 47 }
+
+mtxrInterfaceStatsRxOverflow OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 48 }
+
+mtxrInterfaceStatsRxControl OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 49 }
+
+mtxrInterfaceStatsRxUnknownOp OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 50 }
+
+mtxrInterfaceStatsRxLengthError OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 51 }
+
+mtxrInterfaceStatsRxCodeError OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 52 }
+
+mtxrInterfaceStatsRxCarrierError OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 53 }
+
+mtxrInterfaceStatsRxJabber OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 54 }
+
+mtxrInterfaceStatsRxDrop OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 55 }
+
+mtxrInterfaceStatsTxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 61 }
+
+mtxrInterfaceStatsTxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 62 }
+
+mtxrInterfaceStatsTxTooShort OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 63 }
+
+mtxrInterfaceStatsTx64 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 64 }
+
+mtxrInterfaceStatsTx65To127 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 65 }
+
+mtxrInterfaceStatsTx128To255 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 66 }
+
+mtxrInterfaceStatsTx256To511 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 67 }
+
+mtxrInterfaceStatsTx512To1023 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 68 }
+
+mtxrInterfaceStatsTx1024To1518 OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 69 }
+
+mtxrInterfaceStatsTx1519ToMax OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 70 }
+
+mtxrInterfaceStatsTxTooLong OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 71 }
+
+mtxrInterfaceStatsTxBroadcast OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 72 }
+
+mtxrInterfaceStatsTxPause OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 73 }
+
+mtxrInterfaceStatsTxMulticast OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 74 }
+
+mtxrInterfaceStatsTxUnderrun OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 75 }
+
+mtxrInterfaceStatsTxCollision OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 76 }
+
+mtxrInterfaceStatsTxExcessiveCollision OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 77 }
+
+mtxrInterfaceStatsTxMultipleCollision OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 78 }
+
+mtxrInterfaceStatsTxSingleCollision OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 79 }
+
+mtxrInterfaceStatsTxExcessiveDeferred OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 80 }
+
+mtxrInterfaceStatsTxDeferred OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 81 }
+
+mtxrInterfaceStatsTxLateCollision OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 82 }
+
+mtxrInterfaceStatsTxTotalCollision OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 83 }
+
+mtxrInterfaceStatsTxPauseHonored OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 84 }
+
+mtxrInterfaceStatsTxDrop OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 85 }
+
+mtxrInterfaceStatsTxJabber OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 86 }
+
+mtxrInterfaceStatsTxFCSError OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 87 }
+
+mtxrInterfaceStatsTxControl OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 88 }
+
+mtxrInterfaceStatsTxFragment OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 89 }
+
+mtxrInterfaceStatsLinkDowns OBJECT-TYPE
+ SYNTAX Counter32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 90 }
+
+mtxrInterfaceStatsTxRx1024ToMax OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrInterfaceStatsEntry 91 }
+
+mtxrInterfaceStatsGroup OBJECT-GROUP OBJECTS {
+ mtxrInterfaceStatsName,
+ mtxrInterfaceStatsDriverRxBytes,
+ mtxrInterfaceStatsDriverRxPackets,
+ mtxrInterfaceStatsDriverTxBytes,
+ mtxrInterfaceStatsDriverTxPackets,
+
+ mtxrInterfaceStatsTxRx64,
+ mtxrInterfaceStatsTxRx65To127,
+ mtxrInterfaceStatsTxRx128To255,
+ mtxrInterfaceStatsTxRx256To511,
+ mtxrInterfaceStatsTxRx512To1023,
+ mtxrInterfaceStatsTxRx1024To1518,
+ mtxrInterfaceStatsTxRx1519ToMax,
+
+ mtxrInterfaceStatsRxBytes,
+ mtxrInterfaceStatsRxPackets,
+ mtxrInterfaceStatsRxTooShort,
+ mtxrInterfaceStatsRx64,
+ mtxrInterfaceStatsRx65To127,
+ mtxrInterfaceStatsRx128To255,
+ mtxrInterfaceStatsRx256To511,
+ mtxrInterfaceStatsRx512To1023,
+ mtxrInterfaceStatsRx1024To1518,
+ mtxrInterfaceStatsRx1519ToMax,
+ mtxrInterfaceStatsRxTooLong,
+ mtxrInterfaceStatsRxBroadcast,
+ mtxrInterfaceStatsRxPause,
+ mtxrInterfaceStatsRxMulticast,
+ mtxrInterfaceStatsRxFCSError,
+ mtxrInterfaceStatsRxAlignError,
+ mtxrInterfaceStatsRxFragment,
+ mtxrInterfaceStatsRxOverflow,
+ mtxrInterfaceStatsRxControl,
+ mtxrInterfaceStatsRxUnknownOp,
+ mtxrInterfaceStatsRxLengthError,
+ mtxrInterfaceStatsRxCodeError,
+ mtxrInterfaceStatsRxCarrierError,
+ mtxrInterfaceStatsRxJabber,
+ mtxrInterfaceStatsRxDrop,
+
+ mtxrInterfaceStatsTxBytes,
+ mtxrInterfaceStatsTxPackets,
+ mtxrInterfaceStatsTxTooShort,
+ mtxrInterfaceStatsTx64,
+ mtxrInterfaceStatsTx65To127,
+ mtxrInterfaceStatsTx128To255,
+ mtxrInterfaceStatsTx256To511,
+ mtxrInterfaceStatsTx512To1023,
+ mtxrInterfaceStatsTx1024To1518,
+ mtxrInterfaceStatsTx1519ToMax,
+ mtxrInterfaceStatsTxTooLong,
+ mtxrInterfaceStatsTxBroadcast,
+ mtxrInterfaceStatsTxPause,
+ mtxrInterfaceStatsTxMulticast,
+ mtxrInterfaceStatsTxUnderrun,
+ mtxrInterfaceStatsTxCollision,
+ mtxrInterfaceStatsTxExcessiveCollision,
+ mtxrInterfaceStatsTxMultipleCollision,
+ mtxrInterfaceStatsTxSingleCollision,
+ mtxrInterfaceStatsTxExcessiveDeferred,
+ mtxrInterfaceStatsTxDeferred,
+ mtxrInterfaceStatsTxLateCollision,
+ mtxrInterfaceStatsTxTotalCollision,
+ mtxrInterfaceStatsTxPauseHonored,
+ mtxrInterfaceStatsTxDrop,
+ mtxrInterfaceStatsTxJabber,
+ mtxrInterfaceStatsTxFCSError,
+ mtxrInterfaceStatsTxControl,
+ mtxrInterfaceStatsTxFragment,
+ mtxrInterfaceStatsLinkDowns,
+ mtxrInterfaceStatsTxRx1024ToMax
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 17 }
+
+-- POE ************************************************************************
+
+mtxrPOETable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrPOEEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Power Over Ethernet"
+ ::= { mtxrPOE 1 }
+
+mtxrPOEEntry OBJECT-TYPE
+ SYNTAX MtxrPOEEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrPOEInterfaceIndex }
+ ::= { mtxrPOETable 1 }
+
+MtxrPOEEntry ::= SEQUENCE {
+ mtxrPOEInterfaceIndex ObjectIndex,
+ mtxrPOEName DisplayString,
+ mtxrPOEStatus INTEGER,
+ mtxrPOEVoltage Voltage,
+ mtxrPOECurrent Integer32,
+ mtxrPOEPower Power
+}
+
+mtxrPOEInterfaceIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPOEEntry 1 }
+
+mtxrPOEName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPOEEntry 2 }
+
+mtxrPOEStatus OBJECT-TYPE
+ SYNTAX INTEGER {
+ disabled(1),
+ waitingForLoad(2),
+ poweredOn(3),
+ overload(4),
+ shortCircuit(5),
+ voltageTooLow(6),
+ currentTooLow(7),
+ powerReset(8),
+ voltageTooHigh(9),
+ controllerError(10),
+ controllerUpgrade(11),
+ poeInDetected(12),
+ noValidPsu(13),
+ controllerInit(14),
+ lowVoltageTooLow(15)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPOEEntry 3 }
+
+mtxrPOEVoltage OBJECT-TYPE
+ SYNTAX Voltage
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "V"
+ ::= { mtxrPOEEntry 4 }
+
+mtxrPOECurrent OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "mA"
+ ::= { mtxrPOEEntry 5 }
+
+mtxrPOEPower OBJECT-TYPE
+ SYNTAX Power
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "W"
+ ::= { mtxrPOEEntry 6 }
+
+mtxrPOEGroup OBJECT-GROUP OBJECTS {
+ mtxrPOEName,
+ mtxrPOEStatus,
+ mtxrPOEVoltage,
+ mtxrPOECurrent,
+ mtxrPOEPower
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 18 }
+
+-- LTE Modem ************************************************************
+
+mtxrLTEModemTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrLTEModemEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "LTE Modems"
+ ::= { mtxrLTEModem 1 }
+
+mtxrLTEModemEntry OBJECT-TYPE
+ SYNTAX MtxrLTEModemEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrLTEModemInterfaceIndex }
+ ::= { mtxrLTEModemTable 1 }
+
+MtxrLTEModemEntry ::= SEQUENCE {
+ mtxrLTEModemInterfaceIndex ObjectIndex,
+ mtxrLTEModemSignalRSSI Integer32,
+ mtxrLTEModemSignalRSRQ Integer32,
+ mtxrLTEModemSignalRSRP Integer32,
+ mtxrLTEModemCellId HexInt,
+ mtxrLTEModemAccessTechnology INTEGER,
+ mtxrLTEModemSignalSINR Integer32,
+ mtxrLTEModemEnbId Integer32,
+ mtxrLTEModemSectorId Integer32,
+ mtxrLTEModemLac Integer32,
+ mtxrLTEModemIMEI DisplayString,
+ mtxrLTEModemIMSI DisplayString,
+ mtxrLTEModemUICC DisplayString,
+ mtxrLTEModemRAT DisplayString
+}
+
+mtxrLTEModemInterfaceIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 1 }
+
+mtxrLTEModemSignalRSSI OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dBm"
+ ::= { mtxrLTEModemEntry 2 }
+
+mtxrLTEModemSignalRSRQ OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dB"
+ ::= { mtxrLTEModemEntry 3 }
+
+mtxrLTEModemSignalRSRP OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dBm"
+ ::= { mtxrLTEModemEntry 4 }
+
+mtxrLTEModemCellId OBJECT-TYPE
+ SYNTAX HexInt
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "current cell ID"
+ ::= { mtxrLTEModemEntry 5 }
+
+mtxrLTEModemAccessTechnology OBJECT-TYPE
+ SYNTAX INTEGER {
+ unknown(-1),
+ gsmcompact(0),
+ gsm(1),
+ utran(2),
+ egprs(3),
+ hsdpa(4),
+ hsupa(5),
+ hsdpahsupa(6),
+ eutran(7),
+ nr-sa(11),
+ nr-nsa(13)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "as reported by +CREG"
+ ::= { mtxrLTEModemEntry 6 }
+
+mtxrLTEModemSignalSINR OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dB"
+ ::= { mtxrLTEModemEntry 7 }
+
+mtxrLTEModemEnbId OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 8 }
+
+mtxrLTEModemSectorId OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 9 }
+
+mtxrLTEModemLac OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 10 }
+
+mtxrLTEModemIMEI OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 11 }
+
+mtxrLTEModemIMSI OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 12 }
+
+mtxrLTEModemUICC OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 13 }
+
+mtxrLTEModemRAT OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrLTEModemEntry 14 }
+
+mtxrLTEModemGroup OBJECT-GROUP OBJECTS {
+ mtxrLTEModemSignalRSSI,
+ mtxrLTEModemSignalRSRQ,
+ mtxrLTEModemSignalRSRP,
+ mtxrLTEModemCellId,
+ mtxrLTEModemAccessTechnology,
+ mtxrLTEModemSignalSINR,
+ mtxrLTEModemEnbId,
+ mtxrLTEModemSectorId,
+ mtxrLTEModemLac,
+ mtxrLTEModemIMEI,
+ mtxrLTEModemIMSI,
+ mtxrLTEModemUICC,
+ mtxrLTEModemRAT
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 19 }
+
+-- Partition ************************************************************
+
+mtxrPartitionTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrPartitionEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "system partitions"
+ ::= { mtxrPartition 1 }
+
+mtxrPartitionEntry OBJECT-TYPE
+ SYNTAX MtxrPartitionEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrPartitionIndex }
+ ::= { mtxrPartitionTable 1 }
+
+MtxrPartitionEntry ::= SEQUENCE {
+ mtxrPartitionIndex ObjectIndex,
+ mtxrPartitionName DisplayString,
+ mtxrPartitionSize Integer32,
+ mtxrPartitionVersion DisplayString,
+ mtxrPartitionActive BoolValue,
+ mtxrPartitionRunning BoolValue
+}
+
+mtxrPartitionIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPartitionEntry 1 }
+
+mtxrPartitionName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPartitionEntry 2 }
+
+mtxrPartitionSize OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "MB"
+ ::= { mtxrPartitionEntry 3 }
+
+mtxrPartitionVersion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPartitionEntry 4 }
+
+mtxrPartitionActive OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPartitionEntry 5 }
+
+mtxrPartitionRunning OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrPartitionEntry 6 }
+
+mtxrPartitionGroup OBJECT-GROUP OBJECTS {
+ mtxrPartitionName,
+ mtxrPartitionSize,
+ mtxrPartitionVersion,
+ mtxrPartitionActive,
+ mtxrPartitionRunning
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 20 }
+
+-- OPTICAL *****************************************************************
+
+mtxrOpticalTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrOpticalTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "SFP and GPON information"
+ ::= { mtxrOptical 1 }
+
+mtxrOpticalTableEntry OBJECT-TYPE
+ SYNTAX MtxrOpticalTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX { mtxrOpticalIndex }
+ ::= { mtxrOpticalTable 1 }
+
+MtxrOpticalTableEntry ::= SEQUENCE {
+ mtxrOpticalIndex ObjectIndex,
+ mtxrOpticalName DisplayString,
+ mtxrOpticalRxLoss BoolValue,
+ mtxrOpticalTxFault BoolValue,
+ mtxrOpticalWavelength GDiv100,
+ mtxrOpticalTemperature Gauge32,
+ mtxrOpticalSupplyVoltage GDiv1000,
+ mtxrOpticalTxBiasCurrent Gauge32,
+ mtxrOpticalTxPower IDiv1000,
+ mtxrOpticalRxPower IDiv1000,
+ mtxrOpticalVendorName DisplayString,
+ mtxrOpticalVendorSerial DisplayString
+
+}
+
+mtxrOpticalGroup OBJECT-GROUP OBJECTS {
+ mtxrOpticalName,
+ mtxrOpticalRxLoss,
+ mtxrOpticalTxFault,
+ mtxrOpticalWavelength,
+ mtxrOpticalTemperature,
+ mtxrOpticalSupplyVoltage,
+ mtxrOpticalTxBiasCurrent,
+ mtxrOpticalTxPower,
+ mtxrOpticalRxPower,
+ mtxrOpticalVendorName,
+ mtxrOpticalVendorSerial
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 6 }
+
+mtxrOpticalIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 1 }
+
+mtxrOpticalName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 2 }
+
+mtxrOpticalRxLoss OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 3 }
+
+mtxrOpticalTxFault OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 4 }
+
+mtxrOpticalWavelength OBJECT-TYPE
+ SYNTAX GDiv100
+ UNITS "nm"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 5 }
+
+mtxrOpticalTemperature OBJECT-TYPE
+ SYNTAX Gauge32
+ UNITS "C"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 6 }
+
+mtxrOpticalSupplyVoltage OBJECT-TYPE
+ SYNTAX GDiv1000
+ UNITS "V"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 7 }
+
+mtxrOpticalTxBiasCurrent OBJECT-TYPE
+ SYNTAX Gauge32
+ UNITS "mA"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 8 }
+
+mtxrOpticalTxPower OBJECT-TYPE
+ SYNTAX IDiv1000
+ UNITS "dBm"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 9 }
+
+mtxrOpticalRxPower OBJECT-TYPE
+ SYNTAX IDiv1000
+ UNITS "dBm"
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 10 }
+
+mtxrOpticalVendorName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 11 }
+
+mtxrOpticalVendorSerial OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrOpticalTableEntry 12 }
+
+-- IPSec *****************************************************************
+
+mtxrIkeSACount OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "IKE SA count"
+ ::= { mtxrIPSec 1 }
+
+mtxrIkeSATable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrIkeSATableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "IKE SA table"
+ ::= { mtxrIPSec 2 }
+
+mtxrIkeSATableEntry OBJECT-TYPE
+ SYNTAX MtxrIkeSATableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ INDEX {
+ mtxrIkeSAIndex
+ }
+ ::= { mtxrIkeSATable 1 }
+
+MtxrIkeSATableEntry ::= SEQUENCE {
+ mtxrIkeSAIndex ObjectIndex,
+ mtxrIkeSAInitiatorCookie IsakmpCookie,
+ mtxrIkeSAResponderCookie IsakmpCookie,
+ mtxrIkeSAResponder BoolValue,
+ mtxrIkeSANatt BoolValue,
+ mtxrIkeSAVersion Gauge32,
+ mtxrIkeSAState INTEGER,
+ mtxrIkeSAUptime TimeTicks,
+ mtxrIkeSASeen TimeTicks,
+ mtxrIkeSAIdentity DisplayString,
+ mtxrIkeSAPh2Count Gauge32,
+ mtxrIkeSALocalAddressType InetAddressType,
+ mtxrIkeSALocalAddress InetAddress,
+ mtxrIkeSALocalPort InetPortNumber,
+ mtxrIkeSAPeerAddressType InetAddressType,
+ mtxrIkeSAPeerAddress InetAddress,
+ mtxrIkeSAPeerPort InetPortNumber,
+ mtxrIkeSADynamicAddressType InetAddressType,
+ mtxrIkeSADynamicAddress InetAddress,
+ mtxrIkeSATxBytes Counter64,
+ mtxrIkeSARxBytes Counter64,
+ mtxrIkeSATxPackets Counter64,
+ mtxrIkeSARxPackets Counter64
+}
+
+mtxrIkeSAGroup OBJECT-GROUP OBJECTS {
+ mtxrIkeSACount,
+ mtxrIkeSAInitiatorCookie,
+ mtxrIkeSAResponderCookie,
+ mtxrIkeSAResponder,
+ mtxrIkeSANatt,
+ mtxrIkeSAVersion,
+ mtxrIkeSAState,
+ mtxrIkeSAUptime,
+ mtxrIkeSASeen,
+ mtxrIkeSAIdentity,
+ mtxrIkeSAPh2Count,
+ mtxrIkeSALocalAddressType,
+ mtxrIkeSALocalAddress,
+ mtxrIkeSALocalPort,
+ mtxrIkeSAPeerAddressType,
+ mtxrIkeSAPeerAddress,
+ mtxrIkeSAPeerPort,
+ mtxrIkeSADynamicAddressType,
+ mtxrIkeSADynamicAddress,
+ mtxrIkeSATxBytes,
+ mtxrIkeSARxBytes,
+ mtxrIkeSATxPackets,
+ mtxrIkeSARxPackets
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 7 }
+
+mtxrIkeSAIndex OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 1 }
+
+mtxrIkeSAInitiatorCookie OBJECT-TYPE
+ SYNTAX IsakmpCookie
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "initiator SPI"
+ ::= { mtxrIkeSATableEntry 2 }
+
+mtxrIkeSAResponderCookie OBJECT-TYPE
+ SYNTAX IsakmpCookie
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "responder SPI"
+ ::= { mtxrIkeSATableEntry 3 }
+
+mtxrIkeSAResponder OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "IKE side"
+ ::= { mtxrIkeSATableEntry 4 }
+
+mtxrIkeSANatt OBJECT-TYPE
+ SYNTAX BoolValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "NAT is detected"
+ ::= { mtxrIkeSATableEntry 5 }
+
+mtxrIkeSAVersion OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "protocol version"
+ ::= { mtxrIkeSATableEntry 6 }
+
+mtxrIkeSAState OBJECT-TYPE
+ SYNTAX INTEGER {
+ exchange(1),
+ established(2),
+ expired(3),
+ eap(4)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 7 }
+
+mtxrIkeSAUptime OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 8 }
+
+mtxrIkeSASeen OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "time elapsed since last valid IKE packet"
+ ::= { mtxrIkeSATableEntry 9 }
+
+mtxrIkeSAIdentity OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "peer identity"
+ ::= { mtxrIkeSATableEntry 10 }
+
+mtxrIkeSAPh2Count OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "total ph2 SA pairs"
+ ::= { mtxrIkeSATableEntry 11 }
+
+mtxrIkeSALocalAddressType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 12 }
+
+mtxrIkeSALocalAddress OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 13 }
+
+mtxrIkeSALocalPort OBJECT-TYPE
+ SYNTAX InetPortNumber
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 14 }
+
+mtxrIkeSAPeerAddressType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 15 }
+
+mtxrIkeSAPeerAddress OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 16 }
+
+mtxrIkeSAPeerPort OBJECT-TYPE
+ SYNTAX InetPortNumber
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 17 }
+
+mtxrIkeSADynamicAddressType OBJECT-TYPE
+ SYNTAX InetAddressType
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrIkeSATableEntry 18 }
+
+mtxrIkeSADynamicAddress OBJECT-TYPE
+ SYNTAX InetAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "dynamic address allocated by mode config"
+ ::= { mtxrIkeSATableEntry 19 }
+
+mtxrIkeSATxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "ph2 SA tx bytes"
+ ::= { mtxrIkeSATableEntry 20 }
+
+mtxrIkeSARxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "ph2 SA rx bytes"
+ ::= { mtxrIkeSATableEntry 21 }
+
+mtxrIkeSATxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "ph2 SA tx packets"
+ ::= { mtxrIkeSATableEntry 22 }
+
+mtxrIkeSARxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "ph2 SA rx packets"
+ ::= { mtxrIkeSATableEntry 23 }
+
+mtxrWifiCapsman OBJECT IDENTIFIER ::= { mtxrWifi 1 }
+
+mtxrWifiCapsmanEnabled OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Indicates whether the Capsman is enabled."
+ ::= { mtxrWifiCapsman 1 }
+
+mtxrWifiCapsmanInterfaces OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "List of interfaces associated with Capsman."
+ ::= { mtxrWifiCapsman 2 }
+
+mtxrWifiCapsmanCACertificate OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "The CA certificate used by Capsman."
+ ::= { mtxrWifiCapsman 3 }
+
+mtxrWifiCapsmanCertificate OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "The local certificate used by Capsman."
+ ::= { mtxrWifiCapsman 4 }
+
+mtxrWifiCapsmanRequirePeerCertificate OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Whether a peer certificate is required."
+ ::= { mtxrWifiCapsman 5 }
+
+mtxrWifiCapsmanPackagePath OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Path to the Capsman package directory."
+ ::= { mtxrWifiCapsman 6 }
+
+mtxrWifiCapsmanUpgradePolicy OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Capsman upgrade policy."
+ ::= { mtxrWifiCapsman 7 }
+
+mtxrWifiCapsmanGeneratedCaCertificate OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Automatically generated CA certificate."
+ ::= { mtxrWifiCapsman 8 }
+
+mtxrWifiCapsmanGeneratedCertificate OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Automatically generated local certificate."
+ ::= { mtxrWifiCapsman 9 }
+
+mtxrWifiCap OBJECT IDENTIFIER ::= { mtxrWifi 2 }
+
+mtxrCapEnabled OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Indicates whether the CAP is enabled."
+ ::= { mtxrWifiCap 1 }
+
+mtxrCapInterfaces OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "List of interfaces used by the CAP."
+ ::= { mtxrWifiCap 2 }
+
+mtxrCapCertificate OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "The local certificate used by the CAP."
+ ::= { mtxrWifiCap 3 }
+
+mtxrCapCapsManAddresses OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Addresses of associated CapsMan controllers."
+ ::= { mtxrWifiCap 4 }
+
+mtxrCapCapsManNames OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Names of associated CapsMan controllers."
+ ::= { mtxrWifiCap 5 }
+
+mtxrCapCapsManCertificateCommonNames OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Common names of CapsMan certificates."
+ ::= { mtxrWifiCap 6 }
+
+mtxrCapLockToCapsMan OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Indicates if the CAP is locked to a specific CapsMan."
+ ::= { mtxrWifiCap 7 }
+
+mtxrCapSlavesStatic OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Indicates if CAP slaves are set to static mode."
+ ::= { mtxrWifiCap 8 }
+
+mtxrCapSlavesDatapath OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Datapath configuration of CAP slaves."
+ ::= { mtxrWifiCap 9 }
+
+mtxrCapRequestedCertificate OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Requested certificate for the CAP."
+ ::= { mtxrWifiCap 10 }
+
+mtxrCapLockedCapsManCommonName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Locked CapsMan common name."
+ ::= { mtxrWifiCap 11 }
+
+mtxrCapCurrentCapsManAddress OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Current CapsMan address being used."
+ ::= { mtxrWifiCap 12 }
+
+mtxrCapCurrentCapsManIdentity OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Current identity of the connected CapsMan."
+ ::= { mtxrWifiCap 13 }
+
+-- Remote Caps *************************************************
+
+mtxrRemoteCapTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWifiRemoteCapEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWifi 3 }
+
+mtxrWifiRemoteCapEntry OBJECT-TYPE
+ SYNTAX MtxrWifiRemoteCapEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Entry containing remote CAP statistics"
+ INDEX { mtxrRemoteCapId }
+ ::= { mtxrRemoteCapTable 1 }
+
+MtxrWifiRemoteCapEntry ::= SEQUENCE {
+ mtxrRemoteCapId ObjectIndex,
+ mtxrRemoteCapAddress DisplayString,
+ mtxrRemoteCapIdentity DisplayString,
+ mtxrRemoteCapBoardName DisplayString,
+ mtxrRemoteCapSerial DisplayString,
+ mtxrRemoteCapVersion DisplayString,
+ mtxrRemoteCapBaseMac MacAddress,
+ mtxrRemoteCapCommonName DisplayString,
+ mtxrRemoteCapState DisplayString
+}
+
+mtxrRemoteCapId OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "ID of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 1 }
+
+mtxrRemoteCapAddress OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "IP address of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 2 }
+
+mtxrRemoteCapIdentity OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Identity name of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 3 }
+
+mtxrRemoteCapBoardName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Board name of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 4 }
+
+mtxrRemoteCapSerial OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Serial number of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 5 }
+
+mtxrRemoteCapVersion OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "RouterOS version of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 6 }
+
+mtxrRemoteCapBaseMac OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Base MAC address of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 7 }
+
+mtxrRemoteCapCommonName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Certificate common name of the remote CAP."
+ ::= { mtxrWifiRemoteCapEntry 8 }
+
+mtxrRemoteCapState OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "State of the remote CAP (e.g., connected, disconnected)."
+ ::= { mtxrWifiRemoteCapEntry 9 }
+
+-- Wifi Registration Table *************************************************
+
+mtxrWifiRegistrationTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWifiRegistrationTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWifi 4 }
+
+mtxrWifiRegistrationTableEntry OBJECT-TYPE
+ SYNTAX MtxrWifiRegistrationTableEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Entry containing wifi registration statistics"
+ INDEX { mtxrWifiRegistrationMacAddress, mtxrWifiRegistrationInterface }
+ ::= { mtxrWifiRegistrationTable 1 }
+
+MtxrWifiRegistrationTableEntry ::= SEQUENCE {
+ mtxrWifiRegistrationMacAddress MacAddress,
+ mtxrWifiRegistrationInterface ObjectIndex,
+ mtxrWifiRegistrationSsid DisplayString,
+ mtxrWifiRegistrationUptime TimeTicks,
+ mtxrWifiRegistrationLastActivity Integer32,
+ mtxrWifiRegistrationSignal Integer32,
+ mtxrWifiRegistrationAuthType DisplayString,
+ mtxrWifiRegistrationBand DisplayString,
+ mtxrWifiRegistrationTxRate Gauge32,
+ mtxrWifiRegistrationRxRate Gauge32,
+ mtxrWifiRegistrationTxPackets Counter64,
+ mtxrWifiRegistrationRxPackets Counter64,
+ mtxrWifiRegistrationTxBytes Counter64,
+ mtxrWifiRegistrationRxBytes Counter64,
+ mtxrWifiRegistrationTxBitsPerSecond Integer32,
+ mtxrWifiRegistrationRxBitsPerSecond Integer32,
+ mtxrWifiRegistrationVlanId Integer32,
+ mtxrWifiRegistrationAuthorized TruthValue
+}
+
+mtxrWifiRegistrationMacAddress OBJECT-TYPE
+ SYNTAX MacAddress
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "MAC address of the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 1 }
+
+mtxrWifiRegistrationInterface OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Interface id of the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 2 }
+
+mtxrWifiRegistrationSsid OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "SSID of the connected access point."
+ ::= { mtxrWifiRegistrationTableEntry 3 }
+
+mtxrWifiRegistrationUptime OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Uptime of the registered connection."
+ ::= { mtxrWifiRegistrationTableEntry 4 }
+
+mtxrWifiRegistrationLastActivity OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Time since the last activity of the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 5 }
+
+mtxrWifiRegistrationSignal OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Signal strength of the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 6 }
+
+mtxrWifiRegistrationAuthType OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Authentication type used by the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 7 }
+
+mtxrWifiRegistrationBand OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Wireless band used by the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 8 }
+
+mtxrWifiRegistrationTxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Transmission rate of the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 9 }
+
+mtxrWifiRegistrationRxRate OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Reception rate of the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 10 }
+
+mtxrWifiRegistrationTxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of transmitted packets."
+ ::= { mtxrWifiRegistrationTableEntry 11 }
+
+mtxrWifiRegistrationRxPackets OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of received packets."
+ ::= { mtxrWifiRegistrationTableEntry 12 }
+
+mtxrWifiRegistrationTxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of transmitted bytes."
+ ::= { mtxrWifiRegistrationTableEntry 13 }
+
+mtxrWifiRegistrationRxBytes OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Number of received bytes."
+ ::= {mtxrWifiRegistrationTableEntry 14 }
+
+mtxrWifiRegistrationTxBitsPerSecond OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Transmission rate in bits per second."
+ ::= { mtxrWifiRegistrationTableEntry 15 }
+
+mtxrWifiRegistrationRxBitsPerSecond OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Reception rate in bits per second."
+ ::= { mtxrWifiRegistrationTableEntry 16 }
+
+mtxrWifiRegistrationVlanId OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "VLAN ID of the registered device."
+ ::= { mtxrWifiRegistrationTableEntry 17 }
+
+mtxrWifiRegistrationAuthorized OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Indicates whether the device is authorized."
+ ::= { mtxrWifiRegistrationTableEntry 18 }
+
+-- Wifi Interfaces ***********************************************
+
+mtxrWifiInterfaces OBJECT-TYPE
+ SYNTAX SEQUENCE OF MtxrWifiInterfacesEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtxrWifi 5 }
+
+mtxrWifiInterfacesEntry OBJECT-TYPE
+ SYNTAX MtxrWifiInterfacesEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "An entry representing WiFi interface"
+ INDEX { mtxrWifiInterfacesId }
+ ::= { mtxrWifiInterfaces 1 }
+
+MtxrWifiInterfacesEntry ::= SEQUENCE {
+ mtxrWifiInterfacesId ObjectIndex,
+ mtxrWifiInterfacesName DisplayString,
+ mtxrWifiInterfacesSsid DisplayString,
+ mtxrWifiInterfacesFreq DisplayString
+}
+
+mtxrWifiInterfacesId OBJECT-TYPE
+ SYNTAX ObjectIndex
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION "Unique identifier for each WiFi interface"
+ ::= { mtxrWifiInterfacesEntry 1 }
+
+mtxrWifiInterfacesName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Name of the WiFi interface"
+ ::= { mtxrWifiInterfacesEntry 2 }
+
+mtxrWifiInterfacesSsid OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "SSID associated with the WiFi interface"
+ ::= { mtxrWifiInterfacesEntry 3 }
+
+mtxrWifiInterfacesFreq OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION "Frequency used by the WiFi interface"
+ ::= { mtxrWifiInterfacesEntry 4 }
+
+-- TRAPS **********************************************************************
+
+mtxrNotifications OBJECT IDENTIFIER ::= { mtxrTraps 0 }
+
+mtxrTrap NOTIFICATION-TYPE
+ STATUS current
+ DESCRIPTION "Mikrotik trap OID"
+ ::= { mtxrNotifications 1 }
+
+mtxrTemperatureException NOTIFICATION-TYPE
+ STATUS current
+ DESCRIPTION "Mikrotik CPU temperature exception trap"
+ ::= { mtxrNotifications 2 }
+
+mtxrTrapGroup NOTIFICATION-GROUP NOTIFICATIONS {
+ mtxrTrap,
+ mtxrTemperatureException
+ }
+ STATUS current
+ DESCRIPTION ""
+ ::= { mtXRouterOsGroups 14 }
+
+-- ***************************************************************************
+
+END
+
diff --git a/roles/routeros/files/routeros-poe-mqtt-publish.sh b/roles/routeros/files/routeros-poe-mqtt-publish.sh
new file mode 100755
index 0000000..4395ba0
--- /dev/null
+++ b/roles/routeros/files/routeros-poe-mqtt-publish.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+set -eu
+umask 077
+
+community="public"
+tlsdir="$(openssl version -d | sed -e 's/^OPENSSLDIR: "\(.\+\)"$/\1/')"
+cafile="${tlsdir}/certs/ca.crt"
+keyfile="${tlsdir}/private/$(hostname -f).key"
+certfile="${tlsdir}/certs/$(hostname -f).crt"
+
+export LDAPTLS_KEY="$keyfile"
+export LDAPTLS_CERT="$certfile"
+
+mqtt_send() {
+ topic="$1"
+ value="$2"
+ mosquitto_pub -h mqtt02.home.foo.sh -t "$topic" -m "$value" \
+ --cafile "$cafile" --key "$keyfile" --cert "$certfile"
+}
+
+snmp_get() {
+ host="$1"
+ key="$2"
+ snmpget -v 1 -c "$community" "$host" -Oqv -m MIKROTIK-MIB "$key" | tr -d '"'
+}
+
+# only run script if first vrrp interface is in master state
+if [ "${1:-}" != "-f" ]; then
+ for state in /run/keepalived/*.state ; do
+ if [ "$(cat "$state")" != "MASTER" ]; then
+ exit 0
+ fi
+ break
+ done
+fi
+
+ldapsearch -Q -LLL -Y EXTERNAL "(&(objectClass=device)(description=MikroTik *))" cn | \
+ awk '{ if ($1 == "cn:") print $2 }' | while read -r name
+do
+ snmpwalk -v 1 -c "$community" "$name" -Oq -m MIKROTIK-MIB \
+ MIKROTIK-MIB::mtxrPOEStatus | while read -r port status
+ do
+ port="$(echo "$port" | cut -d "." -f 2)"
+ [ "$status" = "poweredOn" ] || continue
+
+ device="$(snmp_get "$name" "SNMPv2-SMI::mib-2.31.1.1.1.18.${port}")"
+ [ -z "$device" ] && continue
+ location="$(ldapsearch -Q -LLL -Y EXTERNAL \
+ "(&(objectClass=device)(cn=${device}))" l | \
+ sed -n 's/^l: \(.\+\)/\1/p' | tr '[:upper:]' '[:lower:]' | tr ' ' '_')"
+ [ -z "$location" ] && continue
+
+ for key in Current Power Voltage ; do
+ topic="home/${location}/${device}/$(echo "$key" | tr '[:upper:]' '[:lower:]')"
+ value="$(snmp_get "$name" "MIKROTIK-MIB::mtxrPOE${key}.${port}")"
+ mqtt_send "$topic" "$value"
+ done
+ done
+done
diff --git a/roles/routeros/meta/main.yml b/roles/routeros/meta/main.yml
new file mode 100644
index 0000000..d2f9d51
--- /dev/null
+++ b/roles/routeros/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - {role: ldap}
diff --git a/roles/routeros/tasks/main.yml b/roles/routeros/tasks/main.yml
new file mode 100644
index 0000000..f9693ad
--- /dev/null
+++ b/roles/routeros/tasks/main.yml
@@ -0,0 +1,79 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: installed
+ with_items:
+ - mosquitto
+ - net-snmp-utils
+
+- name: Install routeros mib
+ ansible.builtin.copy:
+ dest: /usr/share/snmp/mibs/MIKROTIK-MIB.txt
+ src: mikrotik.mib
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create group
+ ansible.builtin.group:
+ name: routeros
+ system: true
+
+- name: Create user
+ ansible.builtin.user:
+ name: routeros
+ comment: RouterOS Downloader
+ group: routeros
+ groups: hostkey
+ create_home: false
+ home: /var/empty
+ shell: /sbin/nologin
+ system: true
+
+- name: Create download directory
+ ansible.builtin.file:
+ path: /srv/web/oob.foo.sh/routeros
+ state: directory
+ mode: "0775"
+ owner: root
+ group: routeros
+
+- name: Install README.md
+ ansible.builtin.copy:
+ dest: /srv/web/oob.foo.sh/routeros/README.md
+ src: README.md
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Install download script
+ ansible.builtin.copy:
+ dest: /usr/local/bin/download-routeros-firmware
+ src: download-routeros-firmware.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Install download cron job
+ ansible.builtin.cron:
+ name: download-routeros-firmware
+ job: /usr/local/bin/download-routeros-firmware
+ user: routeros
+ hour: "05"
+ minute: "25"
+
+- name: Install mqtt publish script
+ ansible.builtin.copy:
+ dest: /usr/local/bin/routeros-poe-mqtt-publish
+ src: routeros-poe-mqtt-publish.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Install mqtt publish cron job
+ ansible.builtin.cron:
+ name: routeros-poe-mqtt-publish
+ job: /usr/local/bin/routeros-poe-mqtt-publish
+ user: routeros
+ minute: "*/5"
diff --git a/roles/rpm_build/tasks/main.yml b/roles/rpm_build/tasks/main.yml
index b24e952..450048b 100644
--- a/roles/rpm_build/tasks/main.yml
+++ b/roles/rpm_build/tasks/main.yml
@@ -14,7 +14,7 @@
state: directory
owner: root
group: "{{ ansible_wheel }}"
- mode: 0755
+ mode: "0755"
with_items:
- /export/rpmbuild
- /export/rpmbuild/SOURCES
@@ -34,6 +34,6 @@
ansible.builtin.copy:
dest: /root/.rpmmacros
content: "%_topdir /srv/rpmbuild\n"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/rsync/client/tasks/main.yml b/roles/rsync/client/tasks/main.yml
index 1519109..32e4bdc 100644
--- a/roles/rsync/client/tasks/main.yml
+++ b/roles/rsync/client/tasks/main.yml
@@ -11,7 +11,7 @@
ansible.builtin.template:
dest: /usr/local/libexec/rsync-ssl-tunnel
src: rsync-ssl-tunnel.j2
- mode: 0755
+ mode: "0755"
owner: root
group: root
@@ -19,6 +19,6 @@
ansible.builtin.copy:
dest: /usr/local/bin/rsync-ssl
src: rsync-ssl
- mode: 0755
+ mode: "0755"
owner: root
group: root
diff --git a/roles/rsync/server/tasks/main.yml b/roles/rsync/server/tasks/main.yml
index 404f708..71f53fc 100644
--- a/roles/rsync/server/tasks/main.yml
+++ b/roles/rsync/server/tasks/main.yml
@@ -17,7 +17,7 @@
ansible.builtin.template:
dest: /etc/rsyncd.conf
src: rsyncd.conf.j2
- mode: 0644
+ mode: "0644"
owner: root
group: root
@@ -25,7 +25,7 @@
ansible.builtin.template:
dest: /etc/stunnel/rsyncd.conf
src: rsyncd-stunnel.conf.j2
- mode: 0644
+ mode: "0644"
owner: root
group: root
@@ -33,7 +33,7 @@
ansible.builtin.file:
dest: /etc/systemd/system/rsyncd@.service.d
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: root
@@ -41,7 +41,7 @@
ansible.builtin.copy:
dest: /etc/systemd/system/rsyncd@.service.d/stunnel.conf
src: systemd-stunnel.conf
- mode: 0644
+ mode: "0644"
owner: root
group: root
diff --git a/roles/rsync_backup/files/backup-daily.sh b/roles/rsync_backup/files/backup-daily.sh
new file mode 100755
index 0000000..4840732
--- /dev/null
+++ b/roles/rsync_backup/files/backup-daily.sh
@@ -0,0 +1,150 @@
+#!/bin/sh
+
+set -eu
+
+umask 077
+
+ROTATED=30
+
+CONFDIR="/etc/rsync-backup"
+DESTDIR="/srv/backup"
+LOGDIR="/var/log/rsync-backup"
+RUNDIR="/var/run/rsync-backup"
+
+find_rotated() {
+ # sort dailys from oldest to newest, daily.7 daily.6 daily.5 ...
+ find "$1" -mindepth 1 -maxdepth 1 -type d -name "daily.*" | sort -V -r
+}
+
+rotate_dirs() {
+ for host in "$@"; do
+ # rotate dailys starting from oldest
+ if [ ! -d "${DESTDIR}/${host}" ]; then
+ continue
+ fi
+ find_rotated "${DESTDIR}/${host}" | while read -r dir; do
+ ext="${dir##*.}"
+ next="${dir%.*}.$((ext+1))"
+ mv "$dir" "$next"
+ done
+ done
+ # compress logs over 1 day old
+ find "$LOGDIR" -type f -name '*.log' -mtime +1 -execdir gzip -f {} ';'
+}
+
+prune_dirs() {
+ for host in "$@"; do
+ # remove oldest dailys
+ find_rotated "${DESTDIR}/${host}" | while read -r dir ; do
+ num="$(basename "$dir" | sed -e 's/^daily.//')"
+ if [ "$num" -gt $ROTATED ]; then
+ rm -rf "$dir"
+ fi
+ done
+ done
+ # remove logs over ROTATED*2 days old
+ find "$LOGDIR" -type f -name '*.log.gz' -mtime +$((ROTATED*2)) -delete
+}
+
+rsync_pull() {
+ dirs=""
+ opts=""
+ host="$1"
+ conf="${CONFDIR}/${host}.conf"
+ if [ -s "$conf" ] && [ -x "$conf" ]; then
+ # shellcheck source=/dev/null
+ . "$conf" || return
+ else
+ echo "skipped: ${1}" 1>&2
+ return
+ fi
+
+ lockdir="${RUNDIR}/${host}.lock"
+ mkdir -m 0755 "$lockdir" || return
+
+ if [ "$host" = "$(hostname)" ]; then
+ # skip ssh for localhost
+ set -- $dirs
+ else
+ set -- $(for d in $dirs; do echo "${host}:${d}" ; done)
+ fi
+
+ base="${DESTDIR}/${host}"
+ if [ ! -d "$base" ]; then
+ mkdir -m 0700 "$base" || return
+ fi
+ dest="${base}/daily.0"
+ last="${base}/daily.1"
+ if [ ! -d "$dest" ]; then
+ mkdir -m 0700 "$dest" || return
+ fi
+ if [ -d "$last" ]; then
+ # hardlink unchanged files to previous daily
+ opts="--ignore-existing --link-dest=${last}"
+ fi
+
+ logfile="${LOGDIR}/${host}.$(date +%Y%m%d-%H%M%S).log"
+ if ! /usr/local/bin/rsync \
+ -e "ssh -o BatchMode=yes -i ${CONFDIR}/id_ed25519" \
+ -Raqxz --no-devices $opts \
+ --log-file="$logfile" \
+ "$@" "$dest"
+ then
+ echo "rsync log: ${logfile}" 1>&2
+ fi
+ rmdir "$lockdir"
+}
+
+if [ ! -d "$DESTDIR" ]; then
+ echo "ERROR: ${DESTDIR} does not exist" 1>&2
+ exit 1
+fi
+
+if [ ! -d "$LOGDIR" ]; then
+ echo "ERROR: ${LOGDIR} does not exist" 1>&2
+ exit 1
+fi
+
+if [ ! -d "$RUNDIR" ]; then
+ mkdir -m 0755 "$RUNDIR"
+fi
+
+ALL=false
+PRUNE=false
+ROTATE=false
+while getopts "apr" OPT; do
+ case "$OPT" in
+ a)
+ ALL=true
+ ;;
+ p)
+ PRUNE=true
+ ;;
+ r)
+ ROTATE=true
+ ;;
+ *)
+ echo "Usage: $(basename "$0") [-apr] [host ...]" 1>&2
+ exit 1
+ ;;
+ esac
+done
+shift $((OPTIND-1))
+
+mkdir -m 0755 "${RUNDIR}/daily.lock"
+trap 'rmdir "${RUNDIR}/daily.lock"' EXIT
+
+if [ $ALL ]; then
+ for conf in "${CONFDIR}"/*.conf ; do
+ host="$(basename "$conf" ".conf")"
+ set -- "$host" "$@"
+ done
+fi
+
+$ROTATE && rotate_dirs "$@"
+
+for host in "$@" ; do
+ rsync_pull "$host"
+done
+
+$PRUNE && prune_dirs "$@"
diff --git a/roles/web_logs/meta/main.yml b/roles/rsync_backup/meta/main.yml
similarity index 65%
rename from roles/web_logs/meta/main.yml
rename to roles/rsync_backup/meta/main.yml
index 61cc3ce..a6cb84e 100644
--- a/roles/web_logs/meta/main.yml
+++ b/roles/rsync_backup/meta/main.yml
@@ -1,3 +1,4 @@
---
dependencies:
+ - {role: backup_base}
- {role: ssh_known_hosts}
diff --git a/roles/rsync_backup/tasks/main.yml b/roles/rsync_backup/tasks/main.yml
new file mode 100644
index 0000000..d0cfa26
--- /dev/null
+++ b/roles/rsync_backup/tasks/main.yml
@@ -0,0 +1,51 @@
+---
+- name: Copy backup script
+ ansible.builtin.copy:
+ dest: /usr/local/sbin/backup-daily
+ src: backup-daily.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/rsync-backup
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create logdir
+ ansible.builtin.file:
+ path: /var/log/rsync-backup
+ state: directory
+ mode: "0700"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create ssh keys
+ ansible.builtin.command:
+ argv:
+ - ssh-keygen
+ - -t
+ - ed25519
+ - -C
+ - "root@{{ inventory_hostname }}"
+ - -N
+ - ""
+ - -f
+ - /etc/rsync-backup/id_ed25519
+ creates: /etc/rsync-backup/id_ed25519
+
+- name: Fetch ssh public key
+ ansible.builtin.fetch:
+ src: /etc/rsync-backup/id_ed25519.pub
+ dest: ../files/ssh/rsync-backup.pub
+ flat: true
+
+- name: Install cron job
+ ansible.builtin.cron:
+ name: daily rsync backup
+ job: /usr/local/sbin/backup-daily -a -p -r
+ hour: "00"
+ minute: "30"
diff --git a/roles/rsyslog/tasks/main.yml b/roles/rsyslog/tasks/main.yml
index 7372753..6cb4537 100644
--- a/roles/rsyslog/tasks/main.yml
+++ b/roles/rsyslog/tasks/main.yml
@@ -11,7 +11,7 @@
ansible.builtin.copy:
dest: /etc/rsyslog.d/all.log.conf
content: "*.* /var/log/all.log\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart rsyslog
@@ -20,7 +20,7 @@
ansible.builtin.template:
dest: /etc/rsyslog.d/remote.conf
src: remote.conf.j2
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart rsyslog
@@ -34,6 +34,6 @@
ansible.builtin.copy:
dest: /etc/logrotate.d/syslog.all
src: logrotate
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/rsyslog/tasks/udp-listen.yml b/roles/rsyslog/tasks/udp-listen.yml
index cf9ac73..1585323 100644
--- a/roles/rsyslog/tasks/udp-listen.yml
+++ b/roles/rsyslog/tasks/udp-listen.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
dest: /etc/rsyslog.d/udp-listen.conf
src: udp-listen.conf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart rsyslog
diff --git a/roles/rsyslog/templates/remote.conf.j2 b/roles/rsyslog/templates/remote.conf.j2
index f93141b..767b9b5 100644
--- a/roles/rsyslog/templates/remote.conf.j2
+++ b/roles/rsyslog/templates/remote.conf.j2
@@ -1,3 +1,6 @@
+# Log with FQDN
+global(LocalHostName="{{ inventory_hostname }}")
+
# Certificates
global(DefaultNetstreamDriverCAFile="{{ tls_bundle }}"
DefaultNetstreamDriverCertFile="{{ tls_certs }}/{{ inventory_hostname }}.crt"
diff --git a/roles/sane/tasks/main.yml b/roles/sane/tasks/main.yml
new file mode 100644
index 0000000..2d707b5
--- /dev/null
+++ b/roles/sane/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+- name: Install packagers
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: installed
+ with_items:
+ - sane-backends
+ - sane-backends-daemon
+
+- name: Enable service
+ ansible.builtin.systemd:
+ name: saned.socket
+ state: started
+ enabled: true
diff --git a/roles/saslauthd/tasks/main.yml b/roles/saslauthd/tasks/main.yml
index d0c7ce8..74023d2 100644
--- a/roles/saslauthd/tasks/main.yml
+++ b/roles/saslauthd/tasks/main.yml
@@ -19,7 +19,7 @@
ansible.builtin.template:
dest: /etc/saslauthd.conf
src: saslauthd.conf.j2
- mode: 0640
+ mode: "0640"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart saslauthd
diff --git a/roles/scanservjs/defaults/main.yml b/roles/scanservjs/defaults/main.yml
new file mode 100644
index 0000000..efff6f8
--- /dev/null
+++ b/roles/scanservjs/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+scanservjs_version: latest
diff --git a/roles/scanservjs/handlers/main.yml b/roles/scanservjs/handlers/main.yml
new file mode 100644
index 0000000..5cffd92
--- /dev/null
+++ b/roles/scanservjs/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart scanservjs
+ ansible.builtin.systemd:
+ name: scanservjs-container
+ daemon-reload: true
+ state: restarted
diff --git a/roles/zoneminder/meta/main.yml b/roles/scanservjs/meta/main.yml
similarity index 53%
rename from roles/zoneminder/meta/main.yml
rename to roles/scanservjs/meta/main.yml
index 39b2859..19b52d0 100644
--- a/roles/zoneminder/meta/main.yml
+++ b/roles/scanservjs/meta/main.yml
@@ -1,4 +1,4 @@
---
dependencies:
- {role: apache}
- - {role: rpmfusion_free_repo}
+ - {role: podman}
diff --git a/roles/scanservjs/tasks/main.yml b/roles/scanservjs/tasks/main.yml
new file mode 100644
index 0000000..9399983
--- /dev/null
+++ b/roles/scanservjs/tasks/main.yml
@@ -0,0 +1,45 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: scanserv
+
+- name: Create user
+ ansible.builtin.user:
+ name: scanserv
+ comment: Podman Scanservjs
+ group: scanserv
+ shell: /sbin/nologin
+
+- name: Enable user lingering
+ ansible.builtin.command:
+ argv:
+ - loginctl
+ - enable-linger
+ - scanserv
+ creates: /var/lib/systemd/linger/scanserv
+
+- name: Create service file
+ ansible.builtin.template:
+ dest: /etc/systemd/system/scanservjs-container.service
+ src: scanservjs-container.service.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart scanservjs
+
+- name: Enable service
+ ansible.builtin.service:
+ name: scanservjs-container
+ state: started
+ enabled: true
+
+- name: Copy apache config
+ ansible.builtin.copy:
+ dest: /etc/httpd/conf.local.d/scanservjs-container.conf
+ content: |
+ ProxyPass /scanservjs/ http://127.0.0.1:8006/
+ ProxyPassReverse /scanservjs/ http://127.0.0.1:8006/
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart apache
diff --git a/roles/scanservjs/templates/scanservjs-container.service.j2 b/roles/scanservjs/templates/scanservjs-container.service.j2
new file mode 100644
index 0000000..157cb4f
--- /dev/null
+++ b/roles/scanservjs/templates/scanservjs-container.service.j2
@@ -0,0 +1,19 @@
+[Unit]
+Description=Scanserv Container
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+User=scanserv
+ExecStartPre=/usr/bin/podman pull docker.io/sbs20/scanservjs:{{ scanservjs_version }}
+ExecStart=/usr/bin/podman run \
+ --rm -p 127.0.0.1:8006:8080 \
+ --network slirp4netns:allow_host_loopback=true \
+ --env "SANED_NET_HOSTS={{ inventory_hostname }}" \
+ --name scanservjs \
+ docker.io/sbs20/scanservjs:{{ scanservjs_version }}
+ExecStop=/usr/bin/podman stop --ignore scanservjs
+ExecStopPost=/usr/bin/podman rm -f --ignore scanservjs
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/selinux/tasks/main.yml b/roles/selinux/tasks/main.yml
index a99d822..a45757c 100644
--- a/roles/selinux/tasks/main.yml
+++ b/roles/selinux/tasks/main.yml
@@ -8,6 +8,6 @@
ansible.builtin.file:
dest: /usr/local/share/selinux
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/sendmail/files/update-sendmail-certs.sh b/roles/sendmail/files/update-sendmail-certs.sh
new file mode 100644
index 0000000..0e0bbc9
--- /dev/null
+++ b/roles/sendmail/files/update-sendmail-certs.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+set -eu
+umask 022
+
+tmpdir="$(mktemp -d -p /etc/mail)"
+trap 'rm -rf "$tmpdir"' EXIT
+chmod 0755 "$tmpdir"
+
+awk '{
+ if ($0 == "-----BEGIN CERTIFICATE-----") cert=""
+ else if ($0 == "-----END CERTIFICATE-----") print cert
+ else cert=cert$0
+}' /etc/pki/tls/certs/ca-bundle.crt /etc/pki/tls/certs/ca.crt | while read -r CERT; do
+ echo "$CERT" | base64 -d | openssl x509 -inform DER > \
+ "${tmpdir}/$(echo "$CERT" | base64 -d | openssl x509 -inform DER -hash -noout).0"
+done
+
+if ! diff -q "$tmpdir" "/etc/mail/certs" > /dev/null 2>&1 ; then
+ rm -rf /etc/mail/certs
+ mv "$tmpdir" /etc/mail/certs
+ exit 0
+fi
+
+exit 1
diff --git a/roles/sendmail/handlers/main.yml b/roles/sendmail/handlers/main.yml
index fb8e4f1..3c47d7f 100644
--- a/roles/sendmail/handlers/main.yml
+++ b/roles/sendmail/handlers/main.yml
@@ -11,9 +11,21 @@
- -C
- /etc/mail
- all
+ register: result
+ changed_when: result.rc == 0
notify: Restart sendmail
- name: Update aliases
ansible.builtin.command:
argv:
- newaliases
+ register: result
+ changed_when: result.rc == 0
+
+- name: Update sendmail root certs
+ ansible.builtin.command:
+ argv:
+ - update-sendmail-certs
+ register: result
+ failed_when: false
+ changed_when: result.rc == 0
diff --git a/roles/sendmail/meta/main.yml b/roles/sendmail/meta/main.yml
index 4dc7ba0..ad8bde3 100644
--- a/roles/sendmail/meta/main.yml
+++ b/roles/sendmail/meta/main.yml
@@ -1,5 +1,5 @@
---
-
dependencies:
- {role: dhparams}
+ - {role: pki}
- {role: saslauthd}
diff --git a/roles/sendmail/tasks/main.yml b/roles/sendmail/tasks/main.yml
index ee11f6e..c247eed 100644
--- a/roles/sendmail/tasks/main.yml
+++ b/roles/sendmail/tasks/main.yml
@@ -12,15 +12,31 @@
ansible.builtin.file:
path: /etc/mail/certs
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
+- name: Add script to update root certs
+ ansible.builtin.copy:
+ dest: /usr/local/sbin/update-sendmail-certs
+ src: update-sendmail-certs.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Update sendmail root certs
+
+- name: Add cronjob to update root certs
+ ansible.builtin.cron:
+ name: update-sendmail-certs
+ job: /usr/local/sbin/update-sendmail-certs
+ hour: "05"
+ minute: "30"
+
- name: Copy private key
ansible.builtin.copy:
dest: "{{ tls_private }}/{{ mail_server }}.key"
src: "{{ item }}"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
with_first_found:
@@ -34,7 +50,7 @@
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ tls_certs }}/{{ mail_server }}.crt"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
validate: /usr/bin/openssl x509 -in %s -noout
@@ -49,7 +65,7 @@
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ tls_certs }}/{{ mail_server }}-chain.crt"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
validate: /usr/bin/openssl x509 -in %s -noout
@@ -68,7 +84,7 @@
ansible.builtin.file:
path: /export/mail
state: directory
- mode: 0775
+ mode: "0775"
owner: root
group: mail
setype: _default
@@ -96,7 +112,7 @@
ansible.builtin.template:
src: sendmail.mc.j2
dest: /etc/mail/sendmail.mc
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
validate: /bin/sh -c '/usr/bin/m4 %s > /dev/null'
@@ -106,7 +122,7 @@
ansible.builtin.copy:
src: "{{ ansible_private }}/files/sendmail/aliases"
dest: /etc/aliases
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Update aliases
diff --git a/roles/sendmail/templates/sendmail.mc.j2 b/roles/sendmail/templates/sendmail.mc.j2
index c0d9b08..ad31555 100644
--- a/roles/sendmail/templates/sendmail.mc.j2
+++ b/roles/sendmail/templates/sendmail.mc.j2
@@ -60,9 +60,11 @@ FEATURE(`accept_unresolvable_domains')dnl
dnl #
define(`confMATCH_GECOS')dnl
define(`confDOMAIN_NAME', `{{ mail_domain }}')dnl
+define(`confHELO_NAME', `mail.{{ mail_domain }}')dnl
define(`confDONT_BLAME_SENDMAIL', `GroupWritableDirpathSafe,GroupWritableIncludeFile,GroupWritableIncludeFileSafe')dnl
dnl #
MAIL_FILTER(`grossd', `S=inet:5523@localhost, T=C:10m;R:5m')
+INPUT_MAIL_FILTER(`opendkim', `S=local:/run/opendkim/opendkim.sock')
dnl
MAILER(smtp)dnl
MAILER(procmail)dnl
diff --git a/roles/sftpbackup/files/backup-sftp.sh b/roles/sftpbackup/files/backup-sftp.sh
deleted file mode 100644
index 0dcc172..0000000
--- a/roles/sftpbackup/files/backup-sftp.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-set -u
-umas 077
-
-TARGET="/export/backup"
-CONFIG="/etc/rclone/rclone.conf"
-LOGDIR="/var/log/rclone"
-RCLONE="/usr/local/bin/rclone"
-
-timestamp="$(date %Y%m%d)"
-
-if [ ! -d "$TARGET" ]; then
- echo "ERR: Destination directory '${TARGET}' does not exist" 1>&2
- exit 1
-fi
-
-for host in $("$RCLONE" --config "$CONFIG" listremotes | tr -d ":") ; do
- fqdn="$("$RCLONE" --config "$CONFIG" config show "$host" | \
- awk '{ if ($1 == "host") print $3 }')"
- if [ ! -d "${TARGET}/${fqdn}" ]; then
- mkdir "${TARGET}/${fqdn}"
- fi
- log="${LOGDIR}/${fqdn}.${timestamp}.log"
- if ! "$RCLONE" --config "$CONFIG" --log-file "$log" --log-level INFO \
- sync "${host}:/" "${TARGET}/${fqdn}/"; then
- cat "$log"
- fi
-done
diff --git a/roles/sftpbackup/tasks/main.yml b/roles/sftpbackup/tasks/main.yml
deleted file mode 100644
index e131de3..0000000
--- a/roles/sftpbackup/tasks/main.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-- name: Import rclone role
- ansible.builtin.import_role:
- name: rclone
- vars:
- hostgroup: sftpbackup
- remote_user: backup
- destination: /export/backup
- private_key: /root/.ssh/id_ed25519
diff --git a/roles/sftpuser/tasks/main.yml b/roles/sftpuser/tasks/main.yml
deleted file mode 100644
index 6cf95fd..0000000
--- a/roles/sftpuser/tasks/main.yml
+++ /dev/null
@@ -1,35 +0,0 @@
----
-- name: "Create group {{ user }}"
- ansible.builtin.group:
- name: "{{ user }}"
- system: true
-
-- name: "Create user {{ user }}"
- ansible.builtin.user:
- name: "{{ user }}"
- comment: "Service {{ user }}"
- createhome: false
- group: "{{ user }}"
- home: /var/empty
- shell: /sbin/nologin
- system: true
-
-- name: "Create authorized_keys for {{ user }}"
- ansible.builtin.copy:
- dest: "/etc/ssh/authorized_keys.{{ user }}"
- content: "{{ publickeys | join('\n') + '\n'}}"
- mode: 0640
- owner: root
- group: "{{ user }}"
-
-- name: Configure sshd chroot
- ansible.builtin.blockinfile:
- path: /etc/ssh/sshd_config
- block: |
- Match User {{ user }}
- ChrootDirectory {{ chroot }}
- ForceCommand internal-sftp
- AuthorizedKeysFile /etc/ssh/authorized_keys.{{ user }}
- marker: "# {mark} ANSIBLE MANAGED BLOCK (user {{ user }})"
- validate: "sshd -t -f %s"
- notify: Restart sshd
diff --git a/roles/shelly_firmware/files/download-shelly-firmware.sh b/roles/shelly_firmware/files/download-shelly-firmware.sh
new file mode 100644
index 0000000..608b156
--- /dev/null
+++ b/roles/shelly_firmware/files/download-shelly-firmware.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -eu
+
+umask 022
+
+cd /srv/web/iot.foo.sh/shelly
+
+PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
+
+URL="http://archive.shelly-tools.de/"
+
+for _prod in $(curl -sSf "${URL}/archive.php" | jq -r '.[].type') ; do
+ _ver="$(curl -sSf "${URL}/archive.php?type=${_prod}" | jq -r \
+ 'max_by(.version[1:] | split(".") | map(try tonumber catch 0)) .version')"
+ _name="$(curl -sSf "${URL}/archive.php?type=${_prod}" | jq -r \
+ 'limit(1; .[].file)')"
+ if [ ! -f "${_prod}.${_ver}.zip" ]; then
+ echo "New firmware for ${_prod} (version ${_ver})"
+ curl -sSf -o "${_prod}.${_ver}.zip" "${URL}/version/${_ver}/${_name}"
+ if [ -h "$_name" ]; then
+ rm -f "$_name"
+ fi
+ ln -s "${_prod}.${_ver}.zip" "$_name"
+ fi
+done
diff --git a/roles/shelly_firmware/tasks/main.yml b/roles/shelly_firmware/tasks/main.yml
new file mode 100644
index 0000000..db0e0ea
--- /dev/null
+++ b/roles/shelly_firmware/tasks/main.yml
@@ -0,0 +1,28 @@
+---
+- name: Install dependencies
+ ansible.builtin.package:
+ name: jq
+ state: installed
+
+- name: Create download directory
+ ansible.builtin.file:
+ path: /srv/web/iot.foo.sh/shelly
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Install download script
+ ansible.builtin.copy:
+ dest: /usr/local/bin/download-shelly-firmware
+ src: download-shelly-firmware.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Install cron job
+ ansible.builtin.cron:
+ name: download-shelly-firmware
+ job: /usr/local/bin/download-shelly-firmware
+ hour: "05"
+ minute: 20
diff --git a/roles/snmp_exporter/defaults/main.yml b/roles/snmp_exporter/defaults/main.yml
new file mode 100644
index 0000000..de468b0
--- /dev/null
+++ b/roles/snmp_exporter/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+snmp_exporter_pkg: "snmp_exporter-{{ snmp_exporter_version }}.linux-amd64"
diff --git a/roles/snmp_exporter/files/snmp_exporter.service b/roles/snmp_exporter/files/snmp_exporter.service
new file mode 100644
index 0000000..f96318e
--- /dev/null
+++ b/roles/snmp_exporter/files/snmp_exporter.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Prometheus SNMP Exporter
+After=syslog.target
+After=network.target
+
+[Service]
+Type=simple
+User=snmp
+Group=snmp
+ExecStart=/usr/local/bin/snmp_exporter --config.file=/etc/snmp_exporter/snmp.yml --web.config.file=/etc/snmp_exporter/web-config.yml
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/snmp_exporter/handlers/main.yml b/roles/snmp_exporter/handlers/main.yml
new file mode 100644
index 0000000..13fdec5
--- /dev/null
+++ b/roles/snmp_exporter/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart snmp_exporter
+ ansible.builtin.systemd:
+ name: snmp_exporter
+ daemon_reload: true
+ state: restarted
diff --git a/roles/snmp_exporter/tasks/main.yml b/roles/snmp_exporter/tasks/main.yml
new file mode 100644
index 0000000..57a557b
--- /dev/null
+++ b/roles/snmp_exporter/tasks/main.yml
@@ -0,0 +1,104 @@
+---
+- name: Create group
+ ansible.builtin.group:
+ name: snmp
+
+- name: Create user
+ ansible.builtin.user:
+ name: snmp
+ comment: Prometheus SNMP Exporter
+ group: snmp
+ create_home: false
+ home: /var/empty
+ shell: /sbin/nologin
+
+- name: Download package
+ ansible.builtin.get_url:
+ url: >-
+ {{
+ "https://github.com/prometheus/snmp_exporter/releases/download/v"
+ + snmp_exporter_version + "/" + snmp_exporter_pkg + ".tar.gz"
+ }}
+ dest: "/usr/local/src/{{ snmp_exporter_pkg }}.tar.gz"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Extract package
+ ansible.builtin.unarchive:
+ src: "/usr/local/src/{{ snmp_exporter_pkg }}.tar.gz"
+ dest: /usr/local/src
+ owner: root
+ group: "{{ ansible_wheel }}"
+ creates: "/usr/local/src/{{ snmp_exporter_pkg }}"
+ remote_src: true
+
+- name: Copy binary
+ ansible.builtin.copy:
+ dest: /usr/local/bin/snmp_exporter
+ src: "/usr/local/src/{{ snmp_exporter_pkg }}/snmp_exporter"
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ remote_src: true
+ notify: Restart snmp_exporter
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/snmp_exporter
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Copy TLS private key
+ ansible.builtin.copy:
+ src: "/srv/ca/private/nms.home.foo.sh.key"
+ dest: "{{ tls_private }}/nms.home.foo.sh.key"
+ mode: "0640"
+ owner: root
+ group: snmp
+ notify: Restart snmp_exporter
+
+- name: Copy TLS certificate
+ ansible.builtin.copy:
+ src: "/srv/ca/certs/hosts/nms.home.foo.sh.crt"
+ dest: "{{ tls_certs }}/nms.home.foo.sh.crt"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart snmp_exporter
+
+- name: Create web-config
+ ansible.builtin.template:
+ dest: /etc/snmp_exporter/web-config.yml
+ src: web-config.yml.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart snmp_exporter
+
+- name: Copy config
+ ansible.builtin.copy:
+ src: "/usr/local/src/{{ snmp_exporter_pkg }}/snmp.yml"
+ dest: /etc/snmp_exporter/snmp.yml
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ remote_src: true
+ notify: Restart snmp_exporter
+
+- name: Create service file
+ ansible.builtin.copy:
+ dest: /etc/systemd/system/snmp_exporter.service
+ src: snmp_exporter.service
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart snmp_exporter
+
+- name: Enable service
+ ansible.builtin.service:
+ name: snmp_exporter
+ state: started
+ enabled: true
diff --git a/roles/snmp_exporter/templates/web-config.yml.j2 b/roles/snmp_exporter/templates/web-config.yml.j2
new file mode 100644
index 0000000..eb60f11
--- /dev/null
+++ b/roles/snmp_exporter/templates/web-config.yml.j2
@@ -0,0 +1,11 @@
+---
+tls_server_config:
+ key_file: {{ tls_private }}/nms.home.foo.sh.key
+ cert_file: {{ tls_certs }}/nms.home.foo.sh.crt
+ client_ca_file: {{ tls_certs }}/ca.crt
+ client_auth_type: RequireAndVerifyClientCert
+ client_allowed_sans:
+{% for host in groups['prometheus'] %}
+ - {{ host }}
+{% endfor %}
+ min_version: TLS13
diff --git a/roles/spamassassin/tasks/main.yml b/roles/spamassassin/tasks/main.yml
index efd698c..93310d5 100644
--- a/roles/spamassassin/tasks/main.yml
+++ b/roles/spamassassin/tasks/main.yml
@@ -8,7 +8,7 @@
ansible.builtin.copy:
dest: /etc/mail/spamassassin/local.cf
src: local.cf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart spamassassin
diff --git a/roles/spamassassin_clamav/tasks/main.yml b/roles/spamassassin_clamav/tasks/main.yml
index 63e9e77..e8db4df 100644
--- a/roles/spamassassin_clamav/tasks/main.yml
+++ b/roles/spamassassin_clamav/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
src: ClamAV.pm
dest: /etc/mail/spamassassin/ClamAV.pm
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart spamassassin
@@ -12,7 +12,7 @@
ansible.builtin.copy:
src: clamav.cf
dest: /etc/mail/spamassassin/clamav.cf
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart spamassassin
diff --git a/roles/spamassassin_razor/tasks/main.yml b/roles/spamassassin_razor/tasks/main.yml
index b6268dc..dce1cfe 100644
--- a/roles/spamassassin_razor/tasks/main.yml
+++ b/roles/spamassassin_razor/tasks/main.yml
@@ -8,7 +8,7 @@
ansible.builtin.file:
path: /var/lib/razor
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
setype: _default
diff --git a/roles/spamassassin_textcat/tasks/main.yml b/roles/spamassassin_textcat/tasks/main.yml
index 2e3daad..08e645f 100644
--- a/roles/spamassassin_textcat/tasks/main.yml
+++ b/roles/spamassassin_textcat/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.copy:
dest: /etc/mail/spamassassin/textcat.pre
content: "loadplugin Mail::SpamAssassin::Plugin::TextCat\n"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart spamassassin
diff --git a/roles/ssh_known_hosts/tasks/main.yml b/roles/ssh_known_hosts/tasks/main.yml
deleted file mode 100644
index e5caeff..0000000
--- a/roles/ssh_known_hosts/tasks/main.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-- name: Create SSH known_hosts
- ansible.builtin.template:
- dest: /etc/ssh/ssh_known_hosts
- src: ssh_known_hosts.j2
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
diff --git a/roles/ssh_known_hosts/templates/ssh_known_hosts.j2 b/roles/ssh_known_hosts/templates/ssh_known_hosts.j2
deleted file mode 100644
index d6fc971..0000000
--- a/roles/ssh_known_hosts/templates/ssh_known_hosts.j2
+++ /dev/null
@@ -1,5 +0,0 @@
-{% for host, vars in hostvars|dictsort %}
-{% if vars["ansible_ssh_host_key_ed25519_public"] is defined %}
-{{ host }} ssh-ed25519 {{ vars["ansible_ssh_host_key_ed25519_public"] }}
-{% endif %}
-{% endfor %}
diff --git a/roles/sshca/files/genkey.sh b/roles/sshca/files/genkey.sh
new file mode 100755
index 0000000..29bd3ed
--- /dev/null
+++ b/roles/sshca/files/genkey.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -eu
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $(basename "$0") " 1>&2
+ exit
+fi
+
+cd /srv/sshca/ca
+
+year="$1"
+if [ "$year" -eq "$year" ] 2> /dev/null; then
+ if [ "$year" -lt "$(date +%Y)" ]; then
+ echo "ERROR: Invalid year \"${year}\", time in the past" 1>&2
+ exit 1
+ fi
+else
+ echo "ERROR: Invalid year \"${year}\"" 1>&2
+ exit 1
+fi
+
+if [ -f "ca.${year}" ]; then
+ echo "ERROR: Key \"${year}\" already exists" 1>&2
+ exit 1
+fi
+
+ssh-keygen -t ed25519 -f "/srv/sshca/ca/ca.${year}" -C "foo.sh - SSH CA ${year}"
diff --git a/roles/sshca/tasks/main.yml b/roles/sshca/tasks/main.yml
new file mode 100644
index 0000000..41edb8b
--- /dev/null
+++ b/roles/sshca/tasks/main.yml
@@ -0,0 +1,36 @@
+---
+- name: Create datadirectories
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ with_items:
+ - /export/sshca
+ - /export/sshca/pubkeys
+
+- name: Create CA directory
+ ansible.builtin.file:
+ path: "/export/sshca/ca"
+ state: directory
+ mode: "0700"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Link datadirectory
+ ansible.builtin.file:
+ dest: /srv/sshca
+ src: /export/sshca
+ state: link
+ owner: root
+ group: "{{ ansible_wheel }}"
+ follow: false
+
+- name: Copy key generation script
+ ansible.builtin.copy:
+ dest: /srv/sshca/ca/genkey.sh
+ src: genkey.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
diff --git a/roles/sshd/tasks/main.yml b/roles/sshd/tasks/main.yml
index ff28d65..a90c594 100644
--- a/roles/sshd/tasks/main.yml
+++ b/roles/sshd/tasks/main.yml
@@ -28,8 +28,8 @@
line: "CRYPTO_POLICY="
notify: Restart sshd
when:
- - ansible_distribution == "CentOS"
- - ansible_distribution_version is version_compare("8", ">=")
+ - ansible_distribution == "Rocky"
+ - ansible_distribution_version | int == 8
- name: Tighten ssh kex algorithm
ansible.builtin.lineinfile:
diff --git a/roles/sshd_cert/defaults/main.yml b/roles/sshd_cert/defaults/main.yml
new file mode 100644
index 0000000..79b179b
--- /dev/null
+++ b/roles/sshd_cert/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+sshd_cert_hostnames: "{{ ssh_hostnames | default([]) + [inventory_hostname] }}"
diff --git a/roles/sftpuser/meta/main.yml b/roles/sshd_cert/meta/main.yml
similarity index 100%
rename from roles/sftpuser/meta/main.yml
rename to roles/sshd_cert/meta/main.yml
diff --git a/roles/sshd_cert/tasks/main.yml b/roles/sshd_cert/tasks/main.yml
new file mode 100644
index 0000000..964696e
--- /dev/null
+++ b/roles/sshd_cert/tasks/main.yml
@@ -0,0 +1,81 @@
+---
+- name: Copy public key for signing
+ ansible.builtin.fetch:
+ src: /etc/ssh/ssh_host_ed25519_key.pub
+ dest: "/srv/sshca/pubkeys/{{ inventory_hostname }}.pub"
+ flat: true
+
+- name: Check status of public key
+ ansible.builtin.stat:
+ path: "/srv/sshca/pubkeys/{{ inventory_hostname }}.pub"
+ changed_when: false
+ failed_when: false
+ check_mode: false
+ delegate_to: localhost
+ register: sshd_cert_pubkey
+
+- name: Check status of certificate
+ ansible.builtin.stat:
+ path: "/srv/sshca/pubkeys/{{ inventory_hostname }}-cert.pub"
+ changed_when: false
+ failed_when: false
+ check_mode: false
+ delegate_to: localhost
+ register: sshd_cert_status
+
+- name: Get certificate info
+ ansible.builtin.command:
+ argv:
+ - ssh-keygen
+ - -L
+ - -f
+ - "/srv/sshca/pubkeys/{{ inventory_hostname }}-cert.pub"
+ changed_when: false
+ failed_when: false
+ check_mode: false
+ when: sshd_cert_status.stat.exists
+ delegate_to: localhost
+ register: sshd_cert_info
+
+- name: Sign certificate
+ ansible.builtin.command:
+ argv:
+ - ssh-keygen
+ - -s
+ - "/srv/sshca/ca/ca.{{ ansible_date_time['year'] }}"
+ - -I
+ - "{{ inventory_hostname }}"
+ - -h
+ - -n
+ - "{{ sshd_cert_hostnames | join(',') }}"
+ - -V
+ - -1h:+365d
+ - -z
+ - "{{ ansible_date_time.epoch }}"
+ - "/srv/sshca/pubkeys/{{ inventory_hostname }}.pub"
+ when: >
+ not sshd_cert_status.stat.exists or
+ sshd_cert_status.stat.mtime | int < sshd_cert_pubkey.stat.mtime | int or
+ (
+ sshd_cert_info.stdout_lines | select('match', '^[ ]*Valid: ') |
+ first | split() | last | to_datetime('%Y-%m-%dT%H:%M:%S')
+ ).strftime('%s') | int < ansible_date_time.epoch | int + 2592000
+ delegate_to: localhost
+
+- name: Install certificate
+ ansible.builtin.copy:
+ dest: /etc/ssh/ssh_host_ed25519_key-cert.pub
+ src: "/srv/sshca/pubkeys/{{ inventory_hostname }}-cert.pub"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart sshd
+
+- name: Enable host certificate
+ ansible.builtin.lineinfile:
+ path: /etc/ssh/sshd_config
+ line: HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
+ regexp: "^(# )?HostCertificate .*"
+ insertafter: "^HostKey .*"
+ validate: "sshd -t -f %s"
+ notify: Restart sshd
diff --git a/roles/sssd/tasks/main.yml b/roles/sssd/tasks/main.yml
index dae5335..1ce5a2a 100644
--- a/roles/sssd/tasks/main.yml
+++ b/roles/sssd/tasks/main.yml
@@ -8,7 +8,7 @@
ansible.builtin.template:
dest: /etc/sssd/sssd.conf
src: sssd.conf.j2
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart sssd
@@ -20,11 +20,15 @@
enabled: true
- name: Get current state of authselect
- ansible.builtin.shell:
- cmd: /usr/bin/authselect current --raw ; /bin/true
+ ansible.builtin.command:
+ argv:
+ - /usr/bin/authselect
+ - current
+ - --raw
register: result
check_mode: false
changed_when: false
+ failed_when: result.rc not in [0, 2]
- name: Switch authselect to use sssd
ansible.builtin.command:
@@ -33,4 +37,6 @@
- select
- sssd
- --force
+ register: result
+ changed_when: result.rc == 0
when: result.stdout.split()[0] != "sssd"
diff --git a/roles/sssd/templates/sssd.conf.j2 b/roles/sssd/templates/sssd.conf.j2
index 82aa6b1..38e7cf8 100644
--- a/roles/sssd/templates/sssd.conf.j2
+++ b/roles/sssd/templates/sssd.conf.j2
@@ -8,11 +8,11 @@ domains = {{ kerberos_realm }}
[pam]
[domain/{{ kerberos_realm }}]
-id_provider = ldap
-auth_provider = krb5
-chpass_provider = ldap
autofs_provider = none
sudo_provider = none
+
+id_provider = ldap
+chpass_provider = ldap
ldap_uri = ldaps://{{ ldap_server[0] }}
ldap_search_base = {{ ldap_basedn }}
ldap_schema = rfc2307bis
@@ -25,4 +25,11 @@ ldap_sasl_mech = EXTERNAL
ldap_tls_cacert = {{ tls_bundle }}
ldap_tls_cert = {{ tls_certs }}/{{ inventory_hostname }}.crt
ldap_tls_key = {{ tls_private }}/{{ inventory_hostname }}.key
+
+auth_provider = krb5
krb5_realm = {{ kerberos_realm }}
+{% if sssd_allow_groups is defined %}
+
+access_provider = simple
+simple_allow_groups = {{ sssd_allow_groups | join(',') }}
+{% endif %}
diff --git a/roles/syslogd/tasks/main.yml b/roles/syslogd/tasks/main.yml
index 498d76c..cd005bc 100644
--- a/roles/syslogd/tasks/main.yml
+++ b/roles/syslogd/tasks/main.yml
@@ -8,7 +8,7 @@
ansible.builtin.file:
path: /var/log/all.log
state: touch
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
when: not result.stat.exists
@@ -24,7 +24,7 @@
path: /etc/newsyslog.conf
regexp: "^/var/log/all.log.*"
line: |-
- /var/log/all.log root:{{ ansible_wheel }} 640 7 * $D0 Z
+ /var/log/all.log root:{{ ansible_wheel }} 640 7 * $D0 Z
- name: Configure certificates for remote logging
ansible.builtin.service:
diff --git a/roles/syslogd/tasks/server.yml b/roles/syslogd/tasks/server.yml
index 2f8f90f..cfd8e92 100644
--- a/roles/syslogd/tasks/server.yml
+++ b/roles/syslogd/tasks/server.yml
@@ -3,7 +3,7 @@
ansible.builtin.file:
dest: "{{ item }}"
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: "{{ ansible_wheel }}"
with_items:
@@ -22,7 +22,7 @@
ansible.builtin.copy:
dest: "{{ tls_private }}/0.0.0.0:6514.key"
src: /srv/letsencrypt/live/loghost.foo.sh/privkey.pem
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart syslogd
@@ -32,7 +32,7 @@
ansible.builtin.copy:
dest: "{{ tls_certs }}/0.0.0.0:6514.crt"
src: /srv/letsencrypt/live/loghost.foo.sh/fullchain.pem
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart syslogd
@@ -46,7 +46,7 @@
# everything goes to archive
*.* /srv/log/all.log
# only local goes to the standard logs
- +{{ inventory_hostname }}
+ +{{ ansible_hostname }}
marker: "# {mark} ANSIBLE MANAGED BLOCK (syslogd)"
notify: Restart syslogd
@@ -59,7 +59,7 @@
ansible.builtin.copy:
dest: /usr/local/sbin/syslog-archive
src: syslog-archive.sh
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/systemd_resolved/files/resolved.conf b/roles/systemd_resolved/files/resolved.conf
new file mode 100644
index 0000000..e4d2629
--- /dev/null
+++ b/roles/systemd_resolved/files/resolved.conf
@@ -0,0 +1,2 @@
+[global-dns-domain-*]
+servers=127.0.0.53
diff --git a/roles/systemd_resolved/handlers/main.yml b/roles/systemd_resolved/handlers/main.yml
new file mode 100644
index 0000000..dd37621
--- /dev/null
+++ b/roles/systemd_resolved/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Restart systemd-resolved
+ ansible.builtin.service:
+ name: systemd-resolved
+ state: restarted
+
+- name: Restart NetworkManager
+ ansible.builtin.service:
+ name: NetworkManager
+ state: restarted
diff --git a/roles/systemd_resolved/tasks/main.yml b/roles/systemd_resolved/tasks/main.yml
new file mode 100644
index 0000000..bb690d6
--- /dev/null
+++ b/roles/systemd_resolved/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: systemd-resolved
+ state: installed
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/systemd/resolved.conf.d
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create config
+ ansible.builtin.template:
+ dest: /etc/systemd/resolved.conf.d/local.conf
+ src: local.conf.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart systemd-resolved
+
+- name: Do not use connection specific DNS servers
+ ansible.builtin.copy:
+ dest: /etc/NetworkManager/conf.d/resolved.conf
+ src: resolved.conf
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart NetworkManager
+
+- name: Enable service
+ ansible.builtin.service:
+ name: systemd-resolved
+ state: started
+ enabled: true
diff --git a/roles/systemd_resolved/templates/local.conf.j2 b/roles/systemd_resolved/templates/local.conf.j2
new file mode 100644
index 0000000..7d8e03d
--- /dev/null
+++ b/roles/systemd_resolved/templates/local.conf.j2
@@ -0,0 +1,4 @@
+[Resolve]
+DNS={% for addr in network_dns_servers %}{{ addr }}#{{ lookup('community.general.dig', addr + '/PTR')[:-1] }} {% endfor %}
+
+DNSOverTLS=yes
diff --git a/roles/telegraf/tasks/main.yml b/roles/telegraf/tasks/main.yml
index 068f1a4..d1ab303 100644
--- a/roles/telegraf/tasks/main.yml
+++ b/roles/telegraf/tasks/main.yml
@@ -1,15 +1,19 @@
---
+- name: Add telegraf to hostkey group
+ ansible.builtin.user:
+ name: _telegraf
+ groups: hostkey
- name: Install packages
ansible.builtin.package:
name: telegraf
state: installed
-- name: Copy config
- ansible.builtin.copy:
+- name: Create config
+ ansible.builtin.template:
dest: /etc/telegraf/telegraf.conf
- src: "{{ ansible_private }}/files/telegraf/telegraf.conf"
- mode: 0640
+ src: telegraf.conf.j2
+ mode: "0640"
owner: root
group: _telegraf
notify: Restart telegraf
diff --git a/roles/telegraf/templates/telegraf.conf.j2 b/roles/telegraf/templates/telegraf.conf.j2
new file mode 100644
index 0000000..07b71ba
--- /dev/null
+++ b/roles/telegraf/templates/telegraf.conf.j2
@@ -0,0 +1,36 @@
+[[outputs.influxdb_v2]]
+ urls = ["https://influxdb.foo.sh:443"]
+ token = "{{ influxdb_token }}"
+ organization = "foo.sh"
+ bucket = "sensordata"
+
+[[inputs.mqtt_consumer]]
+ servers = ["ssl://{{ inventory_hostname }}:8883"]
+ tls_ca = "{{ tls_certs }}/ca.crt"
+ tls_cert = "{{ tls_certs }}/{{ inventory_hostname }}.crt"
+ tls_key = "{{ tls_private }}/{{ inventory_hostname }}.key"
+ topics = [
+ "+/+/+/power",
+ "+/+/+/temperature",
+ "+/+/+/sensor/battery",
+ "+/+/+/sensor/lux",
+ "+/+/+/sensor/state",
+ "+/+/+/sensor/temperature",
+ ]
+ data_type = "float"
+ data_format = "value"
+
+ [[inputs.mqtt_consumer.topic_parsing]]
+ topic = "+/+/+/power"
+ tags = "location/room/device/_"
+ measurement = "_/_/_/power"
+
+ [[inputs.mqtt_consumer.topic_parsing]]
+ topic = "+/+/+/temperature"
+ tags = "location/room/device/_"
+ measurement = "_/_/_/temperature"
+
+ [[inputs.mqtt_consumer.topic_parsing]]
+ topic = "+/+/+/sensor/+"
+ tags = "location/room/device/_/_"
+ measurement = "_/_/_/_/measurement"
diff --git a/roles/tftp/tasks/main.yml b/roles/tftp/tasks/main.yml
index b943c63..bae19d9 100644
--- a/roles/tftp/tasks/main.yml
+++ b/roles/tftp/tasks/main.yml
@@ -34,7 +34,7 @@
ansible.builtin.file:
path: /export/tftpboot
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -51,7 +51,7 @@
ansible.builtin.file:
path: /etc/systemd/system/tftp.service.d
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
when: ansible_service_mgr == "systemd"
@@ -63,7 +63,7 @@
[Service]
ExecStart=
ExecStart=/usr/sbin/in.tftpd -s /srv/tftpboot -u tftpd -c -v
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart tftpd
diff --git a/roles/mirror/thinlinc/files/sync-thinlinc-repo b/roles/thinlinc_mirror/files/sync-thinlinc-repo.sh
similarity index 57%
rename from roles/mirror/thinlinc/files/sync-thinlinc-repo
rename to roles/thinlinc_mirror/files/sync-thinlinc-repo.sh
index 2638197..f510f8f 100755
--- a/roles/mirror/thinlinc/files/sync-thinlinc-repo
+++ b/roles/thinlinc_mirror/files/sync-thinlinc-repo.sh
@@ -1,4 +1,6 @@
-#!/bin/bash
+#!/bin/sh
+
+set -eu
umask 022
@@ -16,8 +18,8 @@ if [ ! -d "${REPODIR}" ]; then
mkdir "${REPODIR}"
fi
-LOCATION=$(curl -s "${BASEURL}/thinlinc/download" | \
- sed -n 's/^.*64-bit.*/\1/p')
+LOCATION=$(curl -sf "${BASEURL}/thinlinc/download/" | \
+ sed -n 's/^.*&2
exit 1
@@ -25,23 +27,26 @@ fi
PKGNAME="$(basename "${LOCATION}")"
if [ ! -f "${REPODIR}/${PKGNAME}" ]; then
- echo "New thinlinc version found"
+ VERSION="$(echo "$PKGNAME" | sed -n 's/^thinlinc-client-\([0-9\.]*\)-[0-9]*\.x86_64\.rpm/\1/p')"
+
+ echo "New thinlinc version ${VERSION} found"
echo ""
+ tmpfile="$(mktemp)"
+ trap 'rm -f "$tmpfile"' EXIT
+
# assume that server version goes in-line with client
echo "Downloading server package:"
- curl -so "${REPODIR}/.server.zip" "${BASEURL}/downloads/server/download.py"
+ curl -sfo "$tmpfile" "${BASEURL}/downloads/server/tl-${VERSION}-server.zip"
echo "Extracting server rpm files:"
- unzip -jd ${REPODIR} ${REPODIR}/.server.zip \*.rpm
- echo "Cleaning up..."
- rm -f ${REPODIR}/.server.zip
- echo ""
+ unzip -jd "$REPODIR" "$tmpfile" \*.rpm
echo "Downloading client rpm package:"
- curl -so "${REPODIR}/${PKGNAME}" "${BASEURL}${LOCATION}"
+ curl -sfo "${REPODIR}/${PKGNAME}" "${LOCATION}"
echo ""
echo "Updating repository metadata:"
createrepo_c "${REPODIR}"
echo ""
-fi
+ unzip -p "$tmpfile" "*release-notes-*.txt"
+fi
diff --git a/roles/mirror/thinlinc/tasks/main.yml b/roles/thinlinc_mirror/tasks/main.yml
similarity index 92%
rename from roles/mirror/thinlinc/tasks/main.yml
rename to roles/thinlinc_mirror/tasks/main.yml
index 4a7f785..2fb0edc 100644
--- a/roles/mirror/thinlinc/tasks/main.yml
+++ b/roles/thinlinc_mirror/tasks/main.yml
@@ -11,7 +11,7 @@
ansible.builtin.file:
path: /srv/mirrors/thinlinc
state: directory
- mode: 0755
+ mode: "0755"
owner: mirror
group: mirror
@@ -27,8 +27,8 @@
- name: Copy sync script
ansible.builtin.copy:
dest: /usr/local/bin/sync-thinlinc-repo
- src: sync-thinlinc-repo
- mode: 0755
+ src: sync-thinlinc-repo.sh
+ mode: "0755"
owner: root
group: root
diff --git a/roles/thinlinc_server/files/tl-setup.local.sh b/roles/thinlinc_server/files/tl-setup.local.sh
index c657426..acd3b39 100755
--- a/roles/thinlinc_server/files/tl-setup.local.sh
+++ b/roles/thinlinc_server/files/tl-setup.local.sh
@@ -1,22 +1,26 @@
#!/bin/sh
+set -eu
+
cat < /root/tl-setup.answer
-install-pygtk=yes
-email-address=adm@foo.sh
-setup-selinux=yes
-setup-nearest=no
-server-type=master
-setup-firewall=no
-install-python-ldap=no
-setup-apparmor=no
-missing-answer=ask
-install-nfs=no
-setup-thinlocal=no
-install-sshd=no
-tlwebadm-password=$(dd if=/dev/urandom count=1 2> /dev/null | base64 | tail -n 1 | cut -c 1-20)
accept-eula=yes
+server-type=master
migrate-conf=old
install-required-libs=yes
+install-nfs=no
+install-sshd=no
+install-gtk=yes
+install-python-ldap=no
+agent-hostname-choice=manual
+manual-agent-hostname=$(hostname -f)
+email-address=adm@foo.sh
+tlwebadm-password=$(dd if=/dev/urandom count=1 2> /dev/null | base64 | tail -n 1 | cut -c 1-20)
+setup-thinlocal=no
+setup-nearest=no
+setup-firewall=no
+setup-selinux=yes
+setup-apparmor=no
+missing-answer=abort
EOF
/opt/thinlinc/sbin/tl-setup -a /root/tl-setup.answer
diff --git a/roles/thinlinc_server/tasks/main.yml b/roles/thinlinc_server/tasks/main.yml
index 554e527..19eca7e 100644
--- a/roles/thinlinc_server/tasks/main.yml
+++ b/roles/thinlinc_server/tasks/main.yml
@@ -5,6 +5,7 @@
state: installed
with_items:
- gtk3
+ - librsvg2
- polkit
- python3
- python3-gobject
@@ -19,16 +20,8 @@
- name: Install packages
ansible.builtin.package:
- name: "{{ item }}"
+ name: "thinlinc-server"
state: installed
- with_items:
- - thinlinc-tladm
- - thinlinc-tlmisc
- - thinlinc-tlmisc-libs
- - thinlinc-tlprinter
- - thinlinc-vnc-server
- - thinlinc-vsm
- - thinlinc-webaccess
- name: Run ThinLinc setup
ansible.builtin.script:
@@ -39,7 +32,7 @@
ansible.builtin.copy:
dest: /etc/polkit-1/rules.d/40-thinlinc-no-auth-dialogs.rules
src: 40-thinlinc-no-auth-dialogs.rules
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
@@ -55,18 +48,11 @@
regexp: "^show_intro=.*"
line: show_intro=false
-- name: Configure vsmagent hostname
- ansible.builtin.lineinfile:
- path: /opt/thinlinc/etc/conf.d/vsmagent.hconf
- regexp: "^agent_hostname=.*"
- line: "agent_hostname={{ inventory_hostname }}"
- notify: Restart vsmagent
-
- name: Copy private key
ansible.builtin.copy:
dest: /opt/thinlinc/etc/tlwebaccess/server.key
src: "{{ item }}"
- mode: 0600
+ mode: "0600"
owner: root
group: "{{ ansible_wheel }}"
with_first_found:
@@ -79,7 +65,7 @@
ansible.builtin.copy:
dest: /opt/thinlinc/etc/tlwebaccess/server.crt
src: "{{ item }}"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
validate: /usr/bin/openssl x509 -in %s -noout
diff --git a/roles/gitea/handlers/main.yml b/roles/tlshd/handlers/main.yml
similarity index 57%
rename from roles/gitea/handlers/main.yml
rename to roles/tlshd/handlers/main.yml
index a8e19c4..ed0f6fd 100644
--- a/roles/gitea/handlers/main.yml
+++ b/roles/tlshd/handlers/main.yml
@@ -1,5 +1,5 @@
---
-- name: Restart gitea
+- name: Restart tlshd
ansible.builtin.service:
- name: gitea
+ name: tlshd
state: restarted
diff --git a/roles/tlshd/tasks/main.yml b/roles/tlshd/tasks/main.yml
new file mode 100644
index 0000000..7105884
--- /dev/null
+++ b/roles/tlshd/tasks/main.yml
@@ -0,0 +1,30 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: ktls-utils
+
+- name: Configure tlshd
+ ansible.builtin.template:
+ dest: /etc/tlshd.conf
+ src: tlshd.conf.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart tlshd
+
+- name: Configure tlshd private key
+ ansible.builtin.copy:
+ dest: "{{ tls_private }}/tlshd.key"
+ src: "{{ tls_private }}/{{ inventory_hostname }}.key"
+ mode: "0600"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ remote_src: true
+ tags: certificates
+ notify: Restart tlshd
+
+- name: Enable tlshd services
+ ansible.builtin.service:
+ name: tlshd
+ state: started
+ enabled: true
diff --git a/roles/tlshd/templates/tlshd.conf.j2 b/roles/tlshd/templates/tlshd.conf.j2
new file mode 100644
index 0000000..5063216
--- /dev/null
+++ b/roles/tlshd/templates/tlshd.conf.j2
@@ -0,0 +1,16 @@
+[debug]
+loglevel=0
+tls=0
+nl=0
+
+[authenticate]
+
+[authenticate.client]
+x509.truststore = {{ tls_certs }}/ca.crt
+x509.certificate = {{ tls_certs }}/{{ inventory_hostname }}.crt
+x509.private_key = {{ tls_private }}/tlshd.key
+
+[authenticate.server]
+x509.truststore = {{ tls_certs }}/ca.crt
+x509.certificate = {{ tls_certs }}/{{ inventory_hostname }}.crt
+x509.private_key = {{ tls_private }}/tlshd.key
diff --git a/roles/udev/handlers/main.yml b/roles/udev/handlers/main.yml
new file mode 100644
index 0000000..46fb293
--- /dev/null
+++ b/roles/udev/handlers/main.yml
@@ -0,0 +1,14 @@
+---
+- name: Reload udev rules
+ ansible.builtin.command:
+ argv:
+ - udevadm
+ - control
+ - --reload-rules
+ notify: Trigger udev rules
+
+- name: Trigger udev rules
+ ansible.builtin.command:
+ argv:
+ - udevadm
+ - trigger
diff --git a/roles/unbound/tasks/main.yml b/roles/unbound/tasks/main.yml
index 1f6699a..a64720b 100644
--- a/roles/unbound/tasks/main.yml
+++ b/roles/unbound/tasks/main.yml
@@ -12,14 +12,25 @@
ansible.builtin.command:
argv:
- unbound-control-setup
- creates: "{{ unbound_control_key }}"
+ creates: "{{ unbound_confdir }}/unbound_control.key"
notify: Restart unbound
+- name: Copy zone files
+ ansible.builtin.copy:
+ dest: "{{ unbound_zonedir }}/{{ item }}"
+ src: "/srv/dns/{{ item }}"
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ with_items: "{{ unbound_zones }}"
+ notify: Restart unbound
+ when: unbound_zones is defined
+
- name: Copy config
ansible.builtin.template:
- dest: "{{ unbound_conf }}"
+ dest: "{{ unbound_confdir }}/unbound.conf"
src: "unbound.conf.{{ inventory_hostname }}.j2"
- mode: 0644
+ mode: "0644"
owner: root
group: "{{ ansible_wheel }}"
validate: "unbound-checkconf %s"
diff --git a/roles/unbound/templates/unbound.conf.dna-gw01.home.foo.sh.j2 b/roles/unbound/templates/unbound.conf.dna-gw01.home.foo.sh.j2
index 7977574..4765817 100644
--- a/roles/unbound/templates/unbound.conf.dna-gw01.home.foo.sh.j2
+++ b/roles/unbound/templates/unbound.conf.dna-gw01.home.foo.sh.j2
@@ -1,14 +1,22 @@
-
server:
- interface: 127.0.0.1
- interface: ::1
+ # https://nlnetlabs.nl/documentation/unbound/howto-optimise/
+ num-threads: {{ ansible_processor_cores }}
+ msg-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+ rrset-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+ infra-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+ key-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+
interface: 172.20.20.10@53
interface: 172.20.20.10@853
+ interface: 172.20.20.11@53
+ interface: 172.20.20.11@853
+ interface: 172.20.20.12@53
+ interface: 172.20.20.12@853
interface: 172.20.21.1@53
tls-service-key: {{ tls_private }}/dns.home.foo.sh.key
tls-service-pem: {{ tls_certs }}/dns.home.foo.sh.crt
- tls-cert-bundle: {{ tls_certs }}/ca.crt
+ tls-cert-bundle: {{ tls_bundle }}
access-control: 127.0.0.0/8 allow
access-control: ::1 allow
@@ -26,9 +34,14 @@ remote-control:
control-enable: yes
control-interface: /var/run/unbound.sock
+forward-zone:
+ name: "."
+ forward-tls-upstream: yes
+ forward-addr: 8.8.8.8@853#dns.google
+ forward-addr: 8.8.4.4@853#dns.google
+
+{% for zone in unbound_zones %}
auth-zone:
- name: "home.foo.sh"
- zonefile: "/var/unbound/db/home.foo.sh"
-auth-zone:
- name: "20.172.in-addr.arpa"
- zonefile: "/var/unbound/db/20.172.in-addr.arpa"
+ name: "{{ zone }}"
+ zonefile: "{{ unbound_zonedir }}/{{ zone }}"
+{% endfor %}
diff --git a/roles/unbound/templates/unbound.conf.dna-gw02.home.foo.sh.j2 b/roles/unbound/templates/unbound.conf.dna-gw02.home.foo.sh.j2
index c7090c2..c08d855 100644
--- a/roles/unbound/templates/unbound.conf.dna-gw02.home.foo.sh.j2
+++ b/roles/unbound/templates/unbound.conf.dna-gw02.home.foo.sh.j2
@@ -1,14 +1,22 @@
-
server:
- interface: 127.0.0.1
- interface: ::1
+ # https://nlnetlabs.nl/documentation/unbound/howto-optimise/
+ num-threads: {{ ansible_processor_cores }}
+ msg-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+ rrset-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+ infra-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+ key-cache-slabs: {{ ansible_processor_cores | int | pow(2) | int }}
+
interface: 172.20.20.10@53
interface: 172.20.20.10@853
+ interface: 172.20.20.11@53
+ interface: 172.20.20.11@853
+ interface: 172.20.20.12@53
+ interface: 172.20.20.12@853
interface: 172.20.21.2@53
tls-service-key: {{ tls_private }}/dns.home.foo.sh.key
tls-service-pem: {{ tls_certs }}/dns.home.foo.sh.crt
- tls-cert-bundle: {{ tls_certs }}/ca.crt
+ tls-cert-bundle: {{ tls_bundle }}
access-control: 127.0.0.0/8 allow
access-control: ::1 allow
@@ -26,9 +34,14 @@ remote-control:
control-enable: yes
control-interface: /var/run/unbound.sock
+forward-zone:
+ name: "."
+ forward-tls-upstream: yes
+ forward-addr: 8.8.8.8@853#dns.google
+ forward-addr: 8.8.4.4@853#dns.google
+
+{% for zone in unbound_zones %}
auth-zone:
- name: "home.foo.sh"
- zonefile: "/var/unbound/db/home.foo.sh"
-auth-zone:
- name: "20.172.in-addr.arpa"
- zonefile: "/var/unbound/db/20.172.in-addr.arpa"
+ name: "{{ zone }}"
+ zonefile: "{{ unbound_zonedir }}/{{ zone }}"
+{% endfor %}
diff --git a/roles/unbound/templates/unbound.conf.zm02.home.foo.sh.j2 b/roles/unbound/templates/unbound.conf.frigate02.home.foo.sh.j2
similarity index 74%
rename from roles/unbound/templates/unbound.conf.zm02.home.foo.sh.j2
rename to roles/unbound/templates/unbound.conf.frigate02.home.foo.sh.j2
index a4d3f59..3f51925 100644
--- a/roles/unbound/templates/unbound.conf.zm02.home.foo.sh.j2
+++ b/roles/unbound/templates/unbound.conf.frigate02.home.foo.sh.j2
@@ -29,10 +29,11 @@ remote-control:
forward-zone:
name: "."
forward-addr: 172.20.20.10@853#dns.home.foo.sh
+ forward-addr: 172.20.20.11@853#dns.home.foo.sh
+ forward-addr: 172.20.20.12@853#dns.home.foo.sh
+{% for zone in unbound_zones %}
auth-zone:
- name: "cam.foo.sh"
- zonefile: "/var/lib/unbound/cam.foo.sh"
-auth-zone:
- name: "26.20.172.in-addr.arpa"
- zonefile: "/var/lib/unbound/26.20.172.in-addr.arpa"
+ name: "{{ zone }}"
+ zonefile: "{{ unbound_zonedir }}/{{ zone }}"
+{% endfor %}
diff --git a/roles/unbound/templates/unbound.conf.nms01.home.foo.sh.j2 b/roles/unbound/templates/unbound.conf.nms01.home.foo.sh.j2
index a842fcd..c29a61c 100644
--- a/roles/unbound/templates/unbound.conf.nms01.home.foo.sh.j2
+++ b/roles/unbound/templates/unbound.conf.nms01.home.foo.sh.j2
@@ -29,10 +29,11 @@ remote-control:
forward-zone:
name: "."
forward-addr: 172.20.20.10@853#dns.home.foo.sh
+ forward-addr: 172.20.20.11@853#dns.home.foo.sh
+ forward-addr: 172.20.20.12@853#dns.home.foo.sh
+{% for zone in unbound_zones %}
auth-zone:
- name: "oob.foo.sh"
- zonefile: "/var/lib/unbound/oob.foo.sh"
-auth-zone:
- name: "25.20.172.in-addr.arpa"
- zonefile: "/var/lib/unbound/25.20.172.in-addr.arpa"
+ name: "{{ zone }}"
+ zonefile: "{{ unbound_zonedir }}/{{ zone }}"
+{% endfor %}
diff --git a/roles/unbound/templates/unbound.conf.print01.home.foo.sh.j2 b/roles/unbound/templates/unbound.conf.print01.home.foo.sh.j2
index 4799b50..481064f 100644
--- a/roles/unbound/templates/unbound.conf.print01.home.foo.sh.j2
+++ b/roles/unbound/templates/unbound.conf.print01.home.foo.sh.j2
@@ -29,10 +29,11 @@ remote-control:
forward-zone:
name: "."
forward-addr: 172.20.20.10@853#dns.home.foo.sh
+ forward-addr: 172.20.20.11@853#dns.home.foo.sh
+ forward-addr: 172.20.20.12@853#dns.home.foo.sh
+{% for zone in unbound_zones %}
auth-zone:
- name: "print.foo.sh"
- zonefile: "/var/lib/unbound/print.foo.sh"
-auth-zone:
- name: "24.20.172.in-addr.arpa"
- zonefile: "/var/lib/unbound/24.20.172.in-addr.arpa"
+ name: "{{ zone }}"
+ zonefile: "{{ unbound_zonedir }}/{{ zone }}"
+{% endfor %}
diff --git a/roles/unbound/vars/OpenBSD.yml b/roles/unbound/vars/OpenBSD.yml
index 4ce4313..5f41acd 100644
--- a/roles/unbound/vars/OpenBSD.yml
+++ b/roles/unbound/vars/OpenBSD.yml
@@ -1,3 +1,4 @@
---
-unbound_conf: /var/unbound/etc/unbound.conf
-unbound_control_key: /var/unbound/etc/unbound_control.key
+unbound_chroot: /var/unbound
+unbound_confdir: "{{ unbound_chroot }}/etc"
+unbound_zonedir: "{{ unbound_chroot }}/db"
diff --git a/roles/unbound/vars/RedHat.yml b/roles/unbound/vars/RedHat.yml
index 48bfadd..816739c 100644
--- a/roles/unbound/vars/RedHat.yml
+++ b/roles/unbound/vars/RedHat.yml
@@ -1,3 +1,3 @@
---
-unbound_conf: /etc/unbound/unbound.conf
-unbound_control_key: /etc/unbound/unbound_control.key
+unbound_confdir: /etc/unbound
+unbound_zonedir: /var/lib/unbound
diff --git a/roles/unbound_exporter/files/unbound_exporter_stunnel.sh b/roles/unbound_exporter/files/unbound_exporter_stunnel.sh
new file mode 100755
index 0000000..8328224
--- /dev/null
+++ b/roles/unbound_exporter/files/unbound_exporter_stunnel.sh
@@ -0,0 +1,10 @@
+#!/bin/ksh
+
+daemon="/usr/local/sbin/stunnel"
+daemon_flags="/etc/unbound_exporter/stunnel.conf"
+
+. /etc/rc.d/rc.subr
+
+rc_reload=NO
+
+rc_cmd $1
diff --git a/roles/unbound_exporter/handlers/main.yml b/roles/unbound_exporter/handlers/main.yml
new file mode 100644
index 0000000..2cd8d99
--- /dev/null
+++ b/roles/unbound_exporter/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Restart unbound_exporter
+ ansible.builtin.service:
+ name: unbound_exporter
+ state: restarted
+
+- name: Restart unbound_exporter_stunnel
+ ansible.builtin.service:
+ name: unbound_exporter_stunnel
+ state: restarted
diff --git a/roles/unbound_exporter/tasks/main.yml b/roles/unbound_exporter/tasks/main.yml
new file mode 100644
index 0000000..b194422
--- /dev/null
+++ b/roles/unbound_exporter/tasks/main.yml
@@ -0,0 +1,60 @@
+---
+- name: Install packages
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: installed
+ with_items:
+ - stunnel
+ - unbound_exporter
+
+- name: Add user to hostkey group
+ ansible.builtin.user:
+ name: _unboundexporter
+ groups: hostkey
+ append: true
+ create_home: false
+ notify: Restart unbound_exporter_stunnel
+
+- name: Create config directory
+ ansible.builtin.file:
+ path: /etc/unbound_exporter
+ state: directory
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+
+- name: Create stunnel config
+ ansible.builtin.template:
+ dest: /etc/unbound_exporter/stunnel.conf
+ src: stunnel.conf.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart unbound_exporter_stunnel
+
+- name: Enable service
+ ansible.builtin.service:
+ name: unbound_exporter
+ state: started
+ enabled: true
+ arguments: >-
+ -unbound.ca
+ -unbound.cert
+ -unbound.host unix:///var/run/unbound.sock
+ -web.listen-address 127.0.0.1:9167
+ notify: Restart unbound_exporter
+
+- name: Create stunnel service config
+ ansible.builtin.copy:
+ dest: /etc/rc.d/unbound_exporter_stunnel
+ src: unbound_exporter_stunnel.sh
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ notify: Restart unbound_exporter_stunnel
+
+- name: Enable stunnel service
+ ansible.builtin.service:
+ name: unbound_exporter_stunnel
+ state: started
+ enabled: true
diff --git a/roles/unbound_exporter/templates/stunnel.conf.j2 b/roles/unbound_exporter/templates/stunnel.conf.j2
new file mode 100644
index 0000000..8f4aab4
--- /dev/null
+++ b/roles/unbound_exporter/templates/stunnel.conf.j2
@@ -0,0 +1,23 @@
+setuid = _unboundexporter
+setgid = _unboundexporter
+
+sslVersionMin = TLSv1.3
+ciphersuites = TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
+curves = X25519:prime256v1:secp384r1
+
+key = {{ tls_private }}/{{ inventory_hostname }}.key
+cert = {{ tls_certs }}/{{ inventory_hostname }}.crt
+
+verify = 2
+CAfile = {{ tls_certs }}/ca.crt
+
+syslog = yes
+
+[unbound_exporter]
+{% for ip in ansible_all_ipv4_addresses %}
+accept = {{ ip }}:9167
+{% endfor %}
+connect = 127.0.0.1:9167
+{% for host in groups['prometheus'] %}
+checkHost = {{ host }}
+{% endfor %}
diff --git a/roles/unwind/handlers/main.yml b/roles/unwind/handlers/main.yml
new file mode 100644
index 0000000..05d7492
--- /dev/null
+++ b/roles/unwind/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart unwind
+ ansible.builtin.service:
+ name: unwind
+ state: restarted
diff --git a/roles/unwind/tasks/main.yml b/roles/unwind/tasks/main.yml
new file mode 100644
index 0000000..99dd212
--- /dev/null
+++ b/roles/unwind/tasks/main.yml
@@ -0,0 +1,16 @@
+---
+- name: Copy config
+ ansible.builtin.template:
+ dest: /etc/unwind.conf
+ src: unwind.conf.j2
+ mode: "0644"
+ owner: root
+ group: "{{ ansible_wheel }}"
+ validate: "unwind -n -f %s"
+ notify: Restart unwind
+
+- name: Enable service
+ ansible.builtin.service:
+ name: unwind
+ state: started
+ enabled: true
diff --git a/roles/unwind/templates/unwind.conf.j2 b/roles/unwind/templates/unwind.conf.j2
new file mode 100644
index 0000000..2a704ce
--- /dev/null
+++ b/roles/unwind/templates/unwind.conf.j2
@@ -0,0 +1,10 @@
+{% if network_dns_servers is defined %}
+forwarder {
+{% for addr in network_dns_servers %}
+ {{ addr }} port 853 authentication name "{{ lookup('community.general.dig', addr + '/PTR')[:-1] }}" DoT
+{% endfor %}
+}
+preference { DoT }
+{% else %}
+preference { oDoT-autoconf }
+{% endif %}
diff --git a/roles/web_build/tasks/main.yml b/roles/web_build/tasks/main.yml
index 6fb8ba2..d2aed36 100644
--- a/roles/web_build/tasks/main.yml
+++ b/roles/web_build/tasks/main.yml
@@ -3,7 +3,7 @@
ansible.builtin.file:
path: /export/web-build
state: directory
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
@@ -20,6 +20,6 @@
ansible.builtin.copy:
dest: /usr/local/bin/web-sync
src: web-sync.sh
- mode: 0755
+ mode: "0755"
owner: root
group: "{{ ansible_wheel }}"
diff --git a/roles/web_logs/files/combine-logs.py b/roles/web_logs/files/combine-logs.py
new file mode 100644
index 0000000..e7044fa
--- /dev/null
+++ b/roles/web_logs/files/combine-logs.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+
+import argparse
+import datetime
+import os
+import sys
+
+from time import mktime
+
+
+def read_line(log, date=None):
+ while True:
+ line = log["fp"].readline().strip()
+ if not line:
+ raise EOFError
+ time = datetime.datetime.strptime(
+ " ".join(line.split()[3:5]), "[%d/%b/%Y:%H:%M:%S +0000]"
+ )
+ if date is not None and time.strftime("%Y-%m-%d") != date:
+ continue
+ log["time"] = time
+ log["line"] = line
+ log["linenum"] += 1
+ break
+
+
+def combine_logs(logfiles, date=None):
+ logs = []
+ for logfile in logfiles:
+ if os.stat(logfile).st_size == 0:
+ continue
+ logs.append(
+ {"fp": open(logfile, "r"), "line": None, "linenum": 0, "time": None}
+ )
+ try:
+ read_line(logs[-1], date)
+ except EOFError:
+ del logs[-1]
+
+ while True:
+ if len(logs) == 0:
+ break
+ logs = sorted(logs, key=lambda x: x["time"])
+ print(logs[0]["line"])
+ try:
+ read_line(logs[0], date)
+ except EOFError:
+ del logs[0]
+
+
+def date_now():
+ return datetime.datetime.now()
+
+
+if __name__ == "__main__":
+ try:
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-d", "--date", default=None)
+ parser.add_argument("logfiles", nargs="+")
+ args = parser.parse_args()
+ if args.date is not None:
+ if args.date == "today":
+ date = date_now().strftime("%Y-%m-%d")
+ elif args.date == "yesterday":
+ date = (date_now() - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
+ else:
+ date = args.date
+ combine_logs(args.logfiles, date=date)
+ except KeyboardInterrupt:
+ sys.ext(1)
diff --git a/roles/web_logs/tasks/main.yml b/roles/web_logs/tasks/main.yml
index 04e1c7e..27bf8ab 100644
--- a/roles/web_logs/tasks/main.yml
+++ b/roles/web_logs/tasks/main.yml
@@ -2,6 +2,7 @@
- name: Create logsync group
ansible.builtin.group:
name: logsync
+ gid: 312
system: true
- name: Create logsync user
@@ -11,72 +12,38 @@
createhome: false
group: logsync
home: /var/empty
- shell: /sbin/nologin
+ shell: /bin/sh
system: true
+ uid: 312
-- name: Create logsync ssh key directory
- ansible.builtin.file:
- path: /etc/ssh/logsync
- state: directory
- mode: 0750
- owner: root
- group: logsync
-
-- name: Create logsync ssh keys
- ansible.builtin.command:
- argv:
- - ssh-keygen
- - -t
- - ed25519
- - -C
- - "logsync@{{ inventory_hostname }}"
- - -N
- - ""
- - -f
- - /etc/ssh/logsync/id_ed25519
- creates: /etc/ssh/logsync/id_ed25519
-
-- name: Fix logsync ssh key permissions
- ansible.builtin.file:
- path: "{{ item }}"
- owner: root
- group: logsync
- mode: 0640
- with_items:
- - /etc/ssh/logsync/id_ed25519
- - /etc/ssh/logsync/id_ed25519.pub
-
-- name: Import rclone role
- ansible.builtin.import_role:
+- name: Include rclone role
+ ansible.builtin.include_role:
name: rclone
vars:
- local_user: logsync
- remote_user: logsync
- hostgroup: webservers
- destination: /var/cache/sync-http-logs
- private_key: /etc/ssh/logsync/id_ed25519
+ rclone_hostgroup: proxy
+ rclone_service: logsync
-- name: Create cache directory
- ansible.builtin.file:
- path: /var/cache/sync-http-logs
- state: directory
- mode: 0750
- owner: logsync
- group: logsync
-
-- name: Create log directory
+- name: Create data directory
ansible.builtin.file:
path: /export/web-log
state: directory
- mode: 0750
+ mode: "0750"
owner: root
group: "{{ ansible_wheel }}"
- name: Link data directory
ansible.builtin.file:
- dest: /srv/web-log
+ path: /srv/web-log
src: /export/web-log
state: link
owner: root
group: "{{ ansible_wheel }}"
follow: false
+
+- name: Copy log combiner
+ ansible.builtin.copy:
+ dest: /usr/local/bin/combine-logs
+ src: combine-logs.py
+ mode: "0755"
+ owner: root
+ group: "{{ ansible_wheel }}"
diff --git a/roles/web_logs/templates/rclone.conf.j2 b/roles/web_logs/templates/rclone.conf.j2
deleted file mode 100644
index 34524ec..0000000
--- a/roles/web_logs/templates/rclone.conf.j2
+++ /dev/null
@@ -1,10 +0,0 @@
-# {{ ansible_managed }}
-{% for host in groups['webservers'] %}
-
-[{{ host.split('.')[0] }}]
-type = sftp
-host = {{ host }}
-user = logsync
-key_file = ~/.ssh/id_ed25519
-known_hosts_file = /etc/ssh/ssh_known_hosts
-{% endfor %}
diff --git a/roles/websockify/tasks/main.yml b/roles/websockify/tasks/main.yml
index 27d1ba0..1388e87 100644
--- a/roles/websockify/tasks/main.yml
+++ b/roles/websockify/tasks/main.yml
@@ -23,7 +23,7 @@
ansible.builtin.template:
dest: /etc/websockify.conf
src: websockify.conf.j2
- mode: 0640
+ mode: "0640"
owner: root
group: websock
notify: Restart websockify
@@ -32,7 +32,7 @@
ansible.builtin.copy:
dest: /etc/rc.d/websockify
src: rc.websockify
- mode: 0555
+ mode: "0555"
owner: root
group: "{{ ansible_wheel }}"
notify: Restart websockify
diff --git a/roles/zoneminder/defaults/main.yml b/roles/zoneminder/defaults/main.yml
deleted file mode 100644
index a4bf72a..0000000
--- a/roles/zoneminder/defaults/main.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-zm_mysql_host: localhost
-zm_mysql_db: zm
-zm_mysql_user: zmuser
diff --git a/roles/zoneminder/tasks/main.yml b/roles/zoneminder/tasks/main.yml
deleted file mode 100644
index 8ee40c0..0000000
--- a/roles/zoneminder/tasks/main.yml
+++ /dev/null
@@ -1,129 +0,0 @@
----
-- name: Fix SELinux contexts from cache directory
- community.general.sefcontext:
- path: "/var/cache/zoneminder(/.*)?"
- setype: httpd_cache_t
-
-- name: Install packages
- ansible.builtin.package:
- name: "{{ item }}"
- state: installed
- with_items:
- - mariadb
- - zoneminder-httpd
-
-- name: Fix SELinux contexts from data directory
- community.general.sefcontext:
- path: "/export/zoneminder(/.*)?"
- setype: zoneminder_var_lib_t
-
-- name: Create data directory
- ansible.builtin.file:
- path: /export/zoneminder
- state: directory
- mode: 0750
- owner: apache
- group: apache
- setype: _default
-
-- name: Link data directory
- ansible.builtin.file:
- dest: /srv/zoneminder
- src: /export/zoneminder
- state: link
- owner: root
- group: "{{ ansible_wheel }}"
- follow: false
-
-- name: Create config
- ansible.builtin.template:
- dest: /etc/zm/conf.d/local.conf
- src: zm.conf
- mode: 0640
- owner: root
- group: apache
- notify: Restart zoneminder
-
-- name: Remove mariadb depency from unit file
- ansible.builtin.shell:
- cmd: >-
- sed -e 's/mariadb\.service//' /lib/systemd/system/zoneminder.service
- > /etc/systemd/system/zoneminder.service
- creates: /etc/systemd/system/zoneminder.service
- warn: false
- notify: Restart zoneminder
- when: zm_mysql_host != "localhost"
-
-- name: Allow zoneminder to read host private key
- ansible.builtin.user:
- name: apache
- groups: hostkey
- append: true
- notify: Restart zoneminder
- when: zm_mysql_host != "localhost"
-
-- name: Loosen SELinux settings
- ansible.posix.seboolean:
- name: "{{ item }}"
- state: true
- persistent: true
- with_items:
- - domain_can_mmap_files
- - nis_enabled
-
-# selinux doesn't allow create this
-- name: Create stub web log
- ansible.builtin.file:
- dest: /var/log/zoneminder/web_php.log
- state: touch
- mode: 0640
- owner: apache
- group: apache
- access_time: preserve
- modification_time: preserve
-
-- name: Link apache config
- ansible.builtin.file:
- dest: /etc/httpd/conf.local.d/zm.conf
- src: /etc/zm/www/zoneminder.httpd.conf
- state: link
- owner: root
- group: "{{ ansible_wheel }}"
- notify: Restart apache
-
-- name: Link apache php config
- ansible.builtin.file:
- dest: /etc/httpd/conf.local.d/php.conf
- src: /etc/httpd/conf.d/php.conf
- state: link
- owner: root
- group: "{{ ansible_wheel }}"
- notify: Restart apache
-
-- name: Configure zoneminder timezone
- ansible.builtin.copy:
- dest: /etc/php.d/timezone.ini
- content: "date.timezone=UTC\n"
- mode: 0644
- owner: root
- group: "{{ ansible_wheel }}"
- notify: Restart apache
-
-# required for database updates to work
-- name: Configure mysql client to use ssl
- ansible.builtin.copy:
- dest: /root/.my.cnf
- content: |
- [client]
- ssl-ca={{ tls_certs }}/ca.crt
- ssl-cert={{ tls_certs }}/{{ inventory_hostname }}.crt
- ssl-key={{ tls_private }}/{{ inventory_hostname }}.key
- mode: 0600
- owner: root
- group: "{{ ansible_wheel }}"
-
-- name: Enable service
- ansible.builtin.service:
- name: zoneminder
- state: started
- enabled: true
diff --git a/roles/zoneminder/templates/zm.conf b/roles/zoneminder/templates/zm.conf
deleted file mode 100644
index 9e29854..0000000
--- a/roles/zoneminder/templates/zm.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-# {{ ansible_managed }}
-
-ZM_DIR_EVENTS=/srv/zoneminder
-
-ZM_DB_HOST={{ zm_mysql_host }}
-ZM_DB_NAME={{ zm_mysql_db}}
-ZM_DB_USER={{ zm_mysql_user }}
-ZM_DB_PASS={{ zm_mysql_pass }}
-{% if zm_mysql_host != "localhost" %}
-ZM_DB_SSL_CA_CERT={{ tls_certs }}/ca.crt
-ZM_DB_SSL_CLIENT_KEY={{ tls_private }}/{{ inventory_hostname }}.key
-ZM_DB_SSL_CLIENT_CERT={{ tls_certs }}/{{ inventory_hostname }}.crt
-{% endif %}
diff --git a/scripts/check-updates b/scripts/check-updates
new file mode 100755
index 0000000..5a00e56
--- /dev/null
+++ b/scripts/check-updates
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -eu
+
+if [ $# -eq 1 ]; then
+ limit="$1"
+elif [ $# -ne 0 ]; then
+ echo "Usage: $(basename "$0") [hostname]" 1>&2
+ exit 1
+else
+ limit="all"
+fi
+
+cd "$(dirname "$0")/.."
+
+ansible-playbook playbooks/manual/check-updates.yml -l "$limit"
diff --git a/site.yml b/site.yml
index 41765a2..bee03dd 100644
--- a/site.yml
+++ b/site.yml
@@ -1,18 +1,20 @@
---
- name: Configure adm hosts
ansible.builtin.import_playbook: playbooks/adm.yml
+- name: Configure audiobooks hosts
+ ansible.builtin.import_playbook: playbooks/audiobooks.yml
- name: Configure backup hosts
ansible.builtin.import_playbook: playbooks/backup.yml
- name: Configure collab hosts
ansible.builtin.import_playbook: playbooks/collab.yml
- name: Configure dna-gw hosts
ansible.builtin.import_playbook: playbooks/dna-gw.yml
+- name: Configure forgejo hosts
+ ansible.builtin.import_playbook: playbooks/forgejo.yml
+- name: Configure frigate hosts
+ ansible.builtin.import_playbook: playbooks/frigate.yml
- name: Configure fsol-gw hosts
ansible.builtin.import_playbook: playbooks/fsol-gw.yml
-- name: Configure gitea-runner hosts
- ansible.builtin.import_playbook: playbooks/gitea-runner.yml
-- name: Configure gitea hosts
- ansible.builtin.import_playbook: playbooks/gitea.yml
- name: Configure homeassistant hosts
ansible.builtin.import_playbook: playbooks/homeassistant.yml
- name: Configure influxdb hosts
@@ -41,10 +43,14 @@
ansible.builtin.import_playbook: playbooks/oci-node.yml
- name: Configure print hosts
ansible.builtin.import_playbook: playbooks/print.yml
+- name: Configure prometheus hosts
+ ansible.builtin.import_playbook: playbooks/prometheus.yml
- name: Configure proxy hosts
ansible.builtin.import_playbook: playbooks/proxy.yml
- name: Configure relay hosts
ansible.builtin.import_playbook: playbooks/relay.yml
+- name: Configure sane hosts
+ ansible.builtin.import_playbook: playbooks/sane.yml
- name: Configure shell hosts
ansible.builtin.import_playbook: playbooks/shell.yml
- name: Configure sqldb hosts
@@ -53,5 +59,3 @@
ansible.builtin.import_playbook: playbooks/static.yml
- name: Configure vmhost hosts
ansible.builtin.import_playbook: playbooks/vmhost.yml
-- name: Configure zm hosts
- ansible.builtin.import_playbook: playbooks/zm.yml
diff --git a/software b/software
index 225d79a..b9a2d06 160000
--- a/software
+++ b/software
@@ -1 +1 @@
-Subproject commit 225d79acad76f0becbd4db481abc7a8039014a8c
+Subproject commit b9a2d06df00afafcc47403cc5334c64c7fa2f594
diff --git a/tests/03-shellcheck.sh b/tests/11-shellcheck.sh
similarity index 100%
rename from tests/03-shellcheck.sh
rename to tests/11-shellcheck.sh
diff --git a/user.list b/user.list
deleted file mode 100644
index 3fc5a6d..0000000
--- a/user.list
+++ /dev/null
@@ -1,17 +0,0 @@
-
-This file lists all users and groups that have reserved uid/gid and are
-created using ansible rules. If a user/group pair is created, they share
-the same uid/gid. If a user is member of a system group, leave the group
-entry empty. If only a group is created, leave the user entry empty.
-
-id user group notes
--------------------------------------------------------------------------------
-301 influxdb influxdb
-302 mongod mongod
-303 gitea gitea
-1001 mirror mirror
-1002 certbot certbot
-1003 collab collab
-1004 docker docker docker registry
-1005 backup backup
-1007 minecraft minecraft
diff --git a/users.md b/users.md
new file mode 100644
index 0000000..7601659
--- /dev/null
+++ b/users.md
@@ -0,0 +1,20 @@
+# List of reserved UID and GID numbers
+
+This file lists all users and groups that have reserved uid/gid and are
+created using ansible rules. If a user/group pair is created, they share
+the same uid/gid. If a user is member of a system group, leave the group
+entry empty. If only a group is created, leave the user entry empty.
+
+| id | user | group | notes |
+|------|------------|------------|-----------------|
+| 301 | influxdb | influxdb | |
+| 302 | mongod | mongod | |
+| 303 | forgejo | forgejo | |
+| 305 | prometheus | prometheus | |
+| 306 | backup | backup | |
+| 307 | minecraft | minecraft | |
+| 308 | certbot | certbot | |
+| 309 | mirror | mirror | |
+| 310 | collab | collab | |
+| 311 | docker | docker | docker registry |
+| 312 | logsync | logsync | nginx log sync |