Compare commits

...

5 commits

13 changed files with 161 additions and 9 deletions

View file

View file

@ -0,0 +1,8 @@
from django.core.management.base import BaseCommand, CommandError
from core.metrics import update_item_count
class Command(BaseCommand):
help = "Refresh the metrics"
def handle(self, *args, **options):
update_item_count()

11
core/core/metrics.py Normal file
View file

@ -0,0 +1,11 @@
from prometheus_client import Gauge
from django_prometheus import exports
from inventory.models import *
g_items_total = Gauge('c3lf_items_total', 'Current Total items')
def update_item_count():
# Get the count of MyModel objects
count = Item.objects.count()
# Set the gauge to the current count
g_items_total.set(count)

View file

@ -70,6 +70,7 @@ INSTALLED_APPS = [
'inventory',
'mail',
'notify_sessions',
'core'
]
REST_FRAMEWORK = {

View file

@ -19,6 +19,8 @@ from django.urls import path, include
from .version import get_info
from .metrics import *
urlpatterns = [
path('djangoadmin/', admin.site.urls),
path('api/2/', include('inventory.api_v2')),

View file

@ -311,6 +311,16 @@
notify:
- restart c3lf-sys3
- name: add c3lf-sys3-cron service
template:
src: templates/c3lf-sys3-cron.service.j2
dest: /etc/systemd/system/c3lf-sys3-cron.service
- name: add c3lf-sys3-cron timer
template:
src: templates/c3lf-sys3-cron.timer.j2
dest: /etc/systemd/system/c3lf-sys3-cron.timer
- name: reload systemd
systemd:
daemon_reload: yes
@ -321,6 +331,12 @@
state: started
enabled: yes
- name: start c3lf-sys3 timer
service:
name: c3lf-sys3-cron.timer
state: started
enabled: yes
- name: add postfix to www-data group
user:
name: postfix
@ -345,6 +361,13 @@
notify:
- restart postfix
- name: configure rspamd dkim
template:
src: templates/rspamd-dkim.cf.j2
dest: /etc/rspamd/local.d/dkim_signing.conf
notify:
- restart rspamd
- name: configure rspamd
copy:
content: |

View file

@ -0,0 +1,13 @@
[Unit]
Description=c3lf sys3 background service
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/c3lf-sys3
ExecStart=/var/www/c3lf-sys3/venv/bin/python3 /var/www/c3lf-sys3/repo/core/manage.py update_metrics
Environment=DJANGO_SETTINGS_MODULE=core.settings
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,9 @@
[Unit]
Description=Run Nextcloud cron.php every 5 minutes
[Timer]
OnCalendar=minutely
Unit=c3lf-sys3-cron.service
[Install]
WantedBy=timers.target

View file

@ -37,7 +37,6 @@ alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, , localhost
relayhost = firefly.lab.or.it
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +

View file

@ -0,0 +1,79 @@
# local.d/dkim_signing.conf
enabled = true;
# If false, messages with empty envelope from are not signed
allow_envfrom_empty = true;
# If true, envelope/header domain mismatch is ignored
allow_hdrfrom_mismatch = false;
# If true, multiple from headers are allowed (but only first is used)
allow_hdrfrom_multiple = false;
# If true, username does not need to contain matching domain
allow_username_mismatch = false;
# Default path to key, can include '$domain' and '$selector' variables
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
# Default selector to use
selector = "dkim";
# If false, messages from authenticated users are not selected for signing
sign_authenticated = true;
# If false, messages from local networks are not selected for signing
sign_local = true;
# Map file of IP addresses/subnets to consider for signing
# sign_networks = "/some/file"; # or url
# Symbol to add when message is signed
symbol = "DKIM_SIGNED";
# Whether to fallback to global config
try_fallback = true;
# Domain to use for DKIM signing: can be "header" (MIME From), "envelope" (SMTP From), "recipient" (SMTP To), "auth" (SMTP username) or directly specified domain name
use_domain = "header";
# Domain to use for DKIM signing when sender is in sign_networks ("header"/"envelope"/"auth")
#use_domain_sign_networks = "header";
# Domain to use for DKIM signing when sender is a local IP ("header"/"envelope"/"auth")
#use_domain_sign_local = "header";
# Whether to normalise domains to eSLD
use_esld = true;
# Whether to get keys from Redis
use_redis = false;
# Hash for DKIM keys in Redis
key_prefix = "DKIM_KEYS";
# map of domains -> names of selectors (since rspamd 1.5.3)
#selector_map = "/etc/rspamd/dkim_selectors.map";
# map of domains -> paths to keys (since rspamd 1.5.3)
#path_map = "/etc/rspamd/dkim_paths.map";
# If `true` get pubkey from DNS record and check if it matches private key
check_pubkey = false;
# Set to `false` if you want to skip signing if public and private keys mismatch
allow_pubkey_mismatch = true;
# Domain specific settings
domain {
# Domain name is used as key
{{ mail_domain }} {
# Private key path
path = "/var/lib/rspamd/dkim/{{ mail_domain }}.key";
# Selector
selector = "ds";
}
}

View file

@ -67,7 +67,7 @@
</template>
<script>
import {mapActions, mapGetters, mapMutations} from 'vuex';
import {mapActions, mapGetters, mapMutations, mapState} from 'vuex';
import Table from '@/components/Table';
import Cards from '@/components/Cards';
import Modal from '@/components/Modal';
@ -83,7 +83,7 @@ export default {
}),
components: {AsyncLoader, AuthenticatedImage, Table, Cards, Modal},
computed: {
...mapGetters(['getEventItems', 'isItemsLoaded', 'layout']),
...mapGetters(['getEventItems', 'isItemsLoaded', 'layout', 'getEventSlug']),
},
methods: {
...mapActions(['deleteItem', 'markItemReturned', 'loadEventItems', 'updateItem', 'scheduleAfterInit']),
@ -95,6 +95,11 @@ export default {
return window.confirm(message);
}
},
watch: {
getEventSlug() {
this.scheduleAfterInit(() => [this.loadEventItems()]);
}
},
mounted() {
this.scheduleAfterInit(() => [this.loadEventItems()]);
}

View file

@ -1,6 +1,7 @@
<template>
<AsyncLoader :loaded="events.length > 0">
<ExpandableTable v-if="!!events" :columns="['slug', 'name']" :items="events" :keyName="'slug'">
<ExpandableTable v-if="!!events" :columns="['slug', 'name']" :items="events.map((e,i)=>({idx: i, ...e}))"
:keyName="'slug'">
<template v-slot:header_actions>
<button class="btn btn-success" @click.prevent="openAddEventModal">
<font-awesome-icon icon="plus"/>
@ -43,7 +44,7 @@
<div class="mt-3">
<label class="mr-3">Addresses: </label>
<div v-for="(address, a_id) in item.addresses" class="btn-group btn-group-sm mr-3"
@click.stop="deleteAddress(id, a_id)">
@click.stop="deleteAddress(item.idx, a_id)">
<button class="btn btn-secondary" disabled style="opacity: 1">
{{ address }}
</button>
@ -52,8 +53,9 @@
</button>
</div>
<div class="btn-group btn-group-sm">
<input type="text" v-model="new_address[id]">
<button class="btn btn-secondary" @click.stop="addAddress(id)" style="white-space: nowrap;">
<input type="text" v-model="new_address[item.idx]">
<button class="btn btn-secondary" @click.stop="addAddress(item.idx)"
style="white-space: nowrap;">
<font-awesome-icon icon="envelope"/>&nbsp;add
</button>
</div>
@ -88,11 +90,11 @@ export default {
if (!this.events[id].addresses.includes(a))
this.events[id].addresses.push(a)
this.new_address[id] = ""
this.updateEvent({id: this.events[id].eid, partial_event: {addresses: this.events[id].addresses}});
this.updateEvent({id: this.events[id].id, partial_event: {addresses: this.events[id].addresses}});
},
deleteAddress(id, a_id) {
this.events[id].addresses = this.events[id].addresses.filter((e, i) => i !== a_id);
this.updateEvent({id: this.events[id].eid, partial_event: {addresses: this.events[id].addresses}});
this.updateEvent({id: this.events[id].id, partial_event: {addresses: this.events[id].addresses}});
}
},
};