1
0
Fork 0

Compare commits

..

513 Commits

Author SHA1 Message Date
Dustin fd400eb1de home-assistant: Fix image refs for Zigbee/ZWaveJS
The _updatebot_ has been running with an old configuration for a while,
so while it was correctly identifying updates to ZWaveJS UI and
Zigbee2MQTT, it was generating overrides for the incorrect OCI image
names.
2025-09-14 15:47:31 -05:00
Dustin 2ef22105a6 Merge pull request 'home-assistant: Update to 2025.8.0' (#77) from updatebot/home-assistant into master
Reviewed-on: #77
2025-09-14 20:09:37 +00:00
Dustin 86546df447 Merge pull request 'paperless-ngx: Update to 2.18.2' (#82) from updatebot/paperless-ngx into master
Reviewed-on: #82
2025-09-14 03:05:37 +00:00
Dustin ff6d4fa6e3 Merge pull request 'authelia: Update to 4.39.8' (#83) from updatebot/authelia into master
Reviewed-on: #83
2025-09-14 03:04:39 +00:00
bot 9f78f01f14 authelia: Update to 4.39.9 2025-09-13 11:32:15 +00:00
bot 82680ae86e gotenberg: Update to 8.23.0 2025-09-13 11:32:13 +00:00
bot 959bef405f paperless-ngx: Update to 2.18.4 2025-09-13 11:32:13 +00:00
bot fc3435a978 zwavejs2mqtt: Update to 11.2.1 2025-09-13 11:32:08 +00:00
bot da2fcdcf28 zigbee2mqtt: Update to 2.6.1 2025-09-13 11:32:07 +00:00
bot 5873892015 piper: Update to 1.6.3 2025-09-13 11:32:07 +00:00
bot 38c0e8ba02 home-assistant: Update to 2025.9.2 2025-09-13 11:32:07 +00:00
Dustin 7158ff89df v-m/alerts: Ignore Restic alert for Purple Pi
The Purple Pi is no more.  We want to keep it's backups around, though,
but we don't need alerts about them.
2025-09-12 07:25:21 -05:00
Dustin 5869afa923 jenkins: Add PVC for airplaypi Buildroot job
Buildroot jobs really benefit from having a persistent workspace volume
instead of an ephemeral one.  This way, only the packages, etc. that
have changed since the last build need to be built, instead of the whole
toolchain and operating system.
2025-09-07 12:24:11 -05:00
Dustin 4c1992b3c9 v-m/vmagent: Start in parallel
As with AlertManager, the point of having multiple replicas of `vmagent`
is so that one is always running, even if the other fails.  Thus, we
want to start the pods in parallel so that if the first one does not
come up, the second one at least has a chance.
2025-09-07 10:49:22 -05:00
Dustin 25d34efb4c v-m/alertmanager: Bring up replicas in parallel
If something prevents the first AlertManager instance from starting, we
don't want to wait forever for it before starting the second.  That
pretty much defeats the purpose of having two instances.  Fortunately,
we can configure Kubernetes to bring up both instances simultaneously by
setting the pod management policyo to `Parallel`.
2025-09-07 10:42:50 -05:00
Dustin e605e3d1ea v-m/alertmanager: Migrate PVC to Synology
We also don't need a 4 GB volume for AlertManager; even 500 MB is
way too big for the tiny amount of data it stores, but that's about the
smallest size a filesystem can be.
2025-09-07 10:42:13 -05:00
Dustin ab38df1d9f Merge branch 'drop-certs' 2025-09-07 10:33:19 -05:00
Dustin a02dfa1dfc cert-manager: Decommission cert-exporter
The `cert-exporter` is no longer needed.  All websites manage their own
certificates with _mod_md_ now, and all internal applications that use
the wildcard certificate fetch it directly from the Kubernetes Secret.
2025-09-07 10:31:36 -05:00
Dustin b068a260e7 cert-manager: Drop HLC certificate
This site now obtains its own certificate using Apache _mod_md_.
2025-09-07 10:30:20 -05:00
Dustin 479a91ae79 Merge branch 'democratic-csi' 2025-09-07 10:25:14 -05:00
Dustin 87331b24b0 v-m/alerts: Ignore Restic alert for bw0
_bw0.pyrocufflink.blue_ has been decommissioned since some time, so it
doesn't get backed up any more.  We want to keep its previous backups
around, though, in case we ever need to restore something.  This
triggers the "no recent backups" alert, since the last snapshot is over
a week old.  Let's ignore that hostname when generating this alert.
2025-09-07 08:27:19 -05:00
Dustin 7ad8fff7c6 v-m/vmagent: Use ephemeral storage
The `vmagent` needs a place to spool data it has not yet sent to
Victoria Metrics, but it doesn't really need to be persistent.  As long
as all of the `vmagent` nodes _and_ all of the `vminsert` nodes do not
go down simultaneously, there shouldn't be any data loss.  If they are
all down at the same time, there's probably something else going on and
lost metrics are the least concerning problem.
2025-09-07 08:27:19 -05:00
Dustin ee88e5f1c9 dynk8s-provisioner: Remove PVC
The _dynk8s-provisioner_ only needs writable storage to store copies of
the AWS SNS notifications it receives for debugging purposes.  We don't
need to keep these around indefinitely, so using ephemeral node-local
storage is sufficient.  I actually want to get rid of that "feature"
anyway...
2025-09-07 08:27:19 -05:00
Dustin cbed5a8d13 jenkins: Drop Gentoo Portage distribution
Now that Aimee OS is based on Buildroot instead of Gentoo, we don't need
to keep syncing and sharing the Gentoo repository.
2025-09-07 08:27:19 -05:00
Dustin e63fd199ec firefly-iii: Prefer running on amd64 nodes
Although Firefly III works on a Raspberry Pi, a few things are pretty
slow.  Notably, the search feature takes a really long time to return
any results, which is particularly annoying when trying to add a receipt
via the Receipts app.  Adding a node affinity rule to prefer running on
an x86_64 machine will ensure that it runs fast whenever possible, but
can fall back to running on a Rasperry Pi if necessary.
2025-09-07 08:27:19 -05:00
Dustin 687775c595 invoice-ninja: Fix error in cron container
The "cron" container has not been working correctly for some time.  No
background tasks are getting run, and this error is printed in the log
every minute:

> `Target class [db.schema] does not exist`

It turns out, this is because of the way the PHP `artisan` tool works.
It MUST be able to write to the code directory, apparently to build some
kind of cache.  There may be a way to cache the data ahead of time, but
I haven't found it yet.  For now, it seems the only way to make
Laravel-based applications run in a container is to make the container
filesystem mutable.
2025-09-07 08:27:19 -05:00
Dustin 0a89502620 20125: Add Music Assistant
Tabitha wants to see Music Assistant in the smart home status app,
mostly to use as a shortcut.
2025-09-07 08:27:19 -05:00
Dustin 92cf0edc4b v-m/scrape: Scrape Music Assistant via Blackbox
Music Assistant doesn't expose any metrics natively.  Since we really
only care about whether or not it's accessible, scraping it with the
blackbox exporter is fine.
2025-09-07 08:27:19 -05:00
Dustin c011a99165 authelia: Allow from pyrocufflink.net
In order to allow access to Authelia from outside the LAN, it needs to
be able to handle the _pyrocufflink.net_ domain in addition to
_pyrocufflink.blue_.  Originally, this was not possible, as Authelia
only supported a single cookie/domain.  Now that it supports multiple
cookies, we can expose both domains.

The main reason for doing this now is use Authelia's password reset
capability for Mom, since she didn't have a password for her Nextcloud
account that she's just begun using.
2025-09-07 08:27:19 -05:00
Dustin 7c9737e092 kitchen: Update DTEX calendar URL
I wrote a Thunderbird add-on for my work computer that periodically
exports my entire DTEX calendar to a file.  Unfortunately, the file it
creates is not directly usable by the kitchen screen server currently;
it seems to use a time zone identifier that `tzinfo` doesn't understand:

```
Error in background update:
Traceback (most recent call last):
  File "/usr/local/kitchen/lib64/python3.12/site-packages/kitchen/service/agenda.py", line 19, in _background_update
    await self._update()
  File "/usr/local/kitchen/lib64/python3.12/site-packages/kitchen/service/agenda.py", line 34, in _update
    calendar = await self.fetch_calendar(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/kitchen/lib64/python3.12/site-packages/kitchen/service/caldav.py", line 39, in fetch_calendar
    return icalendar.Calendar.from_ical(r.text)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/kitchen/lib64/python3.12/site-packages/icalendar/cal.py", line 369, in from_ical
    _timezone_cache[component['TZID']] = component.to_tz()
                                         ^^^^^^^^^^^^^^^^^
  File "/usr/local/kitchen/lib64/python3.12/site-packages/icalendar/cal.py", line 659, in to_tz
    return cls()
           ^^^^^
  File "/usr/local/kitchen/lib64/python3.12/site-packages/pytz/tzinfo.py", line 190, in __init__
    self._transition_info[0])
    ~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range
```

It seems to work fine in Nextcloud, though, so the work-around is to
import it as a subscription in Nextcloud and then read it from there,
using Nextcloud as a sort of proxy.
2025-09-07 08:27:19 -05:00
Dustin 28d6bdc3a9 kitchen: Pin to amd64 nodes
There is not (currently) an aarch64 build of the kitchen screen server,
so we need to force the pod to run on a x86_64 node.  This seems a good
candidate for running on a Raspberry Pi, so I should go ahead and build
a multi-arch image.
2025-09-07 08:27:19 -05:00
Dustin 67a1d8d0d5 democratic-csi: Enable volume resize
_democratic-csi_ can also dynamically resize Synology iSCSI LUNs when
PVC resource requests increase.  This requires enabling the external
resizer in the controller pod and marking the StorageClass as supporting
resize.
2025-09-06 23:49:53 -05:00
Dustin d909fc0566 democratic-csi: Enable volume snapshot support
The _democratic-csi_ controller can create Synology LUN snapshots based
on VolumeSnapshot resources.  This feature can be used to e.g. create
data snapshots before upgrades, etc.
2025-09-06 23:43:25 -05:00
Dustin f3798c49e3 democratic-csi: Initial deployment
Deploying _democratic-csi_ to manage PersistentVolumeClaim resources,
mapping them to iSCSI volumes on the Synology.

Eventually, all Longhorn-managed PVCs will be replaced with Synology
iSCSI volumes.  Getting rid of Longhorn should free up a lot of
resources and remove a point of failure from the cluster.
2025-09-06 22:57:05 -05:00
Dustin e4f3e8254e Merge pull request 'ntfy: Update to 2.14.0' (#79) from updatebot/ntfy into master
Reviewed-on: #79
2025-08-16 19:20:11 +00:00
Dustin 8e968703b3 Merge pull request 'authelia: Update to 4.39.6' (#80) from updatebot/authelia into master
Reviewed-on: #80
2025-08-16 19:17:48 +00:00
Dustin a5fdaff145 Merge pull request 'tika: Update to 3.2.2.0' (#78) from updatebot/paperless-ngx into master
Reviewed-on: #78
2025-08-16 19:17:18 +00:00
bot 6f3919fe06 authelia: Update to 4.39.6 2025-08-16 11:32:12 +00:00
bot e140e9d49d ntfy: Update to 2.14.0 2025-08-16 11:32:10 +00:00
bot f24285d761 tika: Update to 3.2.2.0 2025-08-16 11:32:09 +00:00
Dustin 8a6b41bacc Revert "music-assistant: Tell players to restart on startup"
This hacky work-around is no longer necessary, as I've figured out why
the players don't (always) get rediscovered when the server restarts.
It turns out, Avahi on the firewall was caching responses to the mDNS PTR
requests Music Assistant makes.  Rather than forward the requests to the
other VLANs, it would respond with its cached information, but in a way
that Music Assistant didn't understand.  Setting `cache-entries-max` to
`0` in `avahi-daemon.conf` on the firewall resolved the issue.

This reverts commit 42a7964991.
2025-08-12 20:17:52 -05:00
Dustin e0e3eab8b6 Merge branch 'music-assistant' 2025-08-11 21:00:02 -05:00
Dustin 42a7964991 music-assistant: Tell players to restart on startup
I haven't fully determined why, but when the Music Assistant server
restarts, it marks the _shairport-sync_ players as offline and will not
allow playing to them.  The only way I have found to work around this is
to restart the players after the server restarts.  As that's pretty
cumbersome and annoying, I naturally want to automate it, so I've
created this rudimentary synchronization technique using _ntfy_: each
player listens for notifications on a specific topic, and upon receiving
one, tells _shairport-sync_ to exit.  With the `Restart=` property
configured on the _shairport-sync.service_ unit, _systemd_ will restart
the service, which causes Music Assistant to discover the player again.
2025-08-11 20:59:54 -05:00
Dustin ae1d952297 music-assistant: Initial deployment
_Music Assistant_ is pretty straightforward to deploy, despite
upstream's apparent opinion otherwise.  It just needs a small persistent
volume for its media index and customization.  It does need to use the
host network namespace, though, in order to receive multicast
announcements from e.g. AirPlay players, as it doesn't have any way of
statically configuring them.
2025-08-11 20:43:28 -05:00
Dustin 2a0fdc07df cert-manager: Drop dustinandtabitha.com certificate
This site now obtains its own certificate using Apache _mod_md_.
2025-08-11 08:59:57 -05:00
Dustin 4977f513c5 dch-webhooks: Add role for Jenkins to deploy
Jenkins needs to be able to patch the Deployment to trigger a restart
after it builds a new container image for _dch-webhooks_.

Note that this manifest must be applied on its own **without
Kustomize**.  Kustomize seems to think the `dch-webhooks` in
`resourceNames` refers to the ConfigMap it manages and "helpfully"
renames it with the name suffix hash.  It's _not_ the ConfigMap, though,
but there's not really any way to tell it this.
2025-08-10 17:43:02 -05:00
Dustin 3960552f99 calico: Update to v3.30.2 2025-08-08 11:00:27 -05:00
Dustin aa27579582 cert-manager: Drop dustin.hatch.name certificate
This site now obtains its own certificate using Apache _mod_md_.
2025-08-07 11:26:23 -05:00
Dustin 2b109589c2 h-a/{piper,whisper}: Prefer x86_64 nodes
Without a node affinity rule, Kubernetes applies equal weight to the
"big" x86_64 nodes and the "small" aarch64 ones.  Since we would really
rather Piper and Whisper _not_ run on a Raspberry Pi, we need the rule
to express this.
2025-08-07 10:31:10 -05:00
Dustin ea4e45e479 Revert "h-a: Schedule Piper, Whisper, Mosquitto with HA"
As it turns out, although Home Assistant itself works perfectly fine on
a Raspberry Pi, Piper and Whisper do not.  They are _much_ too slow to
respond to voice commands.

This reverts commit 32666aa628.
2025-08-07 10:26:37 -05:00
Dustin 3896dd67eb Merge pull request 'home-assistant: Update to 2025.7.2' (#73) from updatebot/home-assistant into master
Reviewed-on: #73
2025-08-05 14:17:24 +00:00
Dustin c5545445b6 Merge pull request 'firefly-iii: Update to 6.2.21' (#74) from updatebot/firefly-iii into master
Reviewed-on: #74
2025-08-03 16:41:17 +00:00
Dustin 2a7d531aa3 Merge pull request 'authelia: Update to 4.39.5' (#75) from updatebot/authelia into master
Reviewed-on: #75
2025-08-03 16:35:18 +00:00
Dustin 1998abefbd Merge pull request 'vaultwarden: Update to 1.34.3' (#76) from updatebot/vaultwarden into master
Reviewed-on: #76
2025-08-03 16:34:09 +00:00
Dustin 1ec974fa2d v-m/alerts: Add alert for Internet down 2025-08-03 11:29:41 -05:00
bot b2aa70dff0 vaultwarden: Update to 1.34.3 2025-08-02 11:32:29 +00:00
bot 28c7f98cb5 authelia: Update to 4.39.5 2025-08-02 11:32:19 +00:00
bot 14d6af7886 firefly-iii: Update to 6.2.21 2025-08-02 11:32:11 +00:00
bot a4d05c7288 zwavejs2mqtt: Update to 11.0.1 2025-08-02 11:32:07 +00:00
bot c10aef5d65 zigbee2mqtt: Update to 2.6.0 2025-08-02 11:32:07 +00:00
bot 474b068708 home-assistant: Update to 2025.7.4 2025-08-02 11:32:06 +00:00
Dustin 024eaf241f Merge remote-tracking branch 'refs/remotes/origin/master' 2025-07-29 21:56:18 -05:00
Dustin a6618cac11 h-a: Update taints for Zigbee/Zwave controllers
With the introduction of the two new Raspberry Pi nodes that I intend to
be used for anything that supports running on aarch64, I'm eliminating
the `du5t1n.me/machine=raspberrypi` taint.  It no longer makes sense, as
the only node that has it is the Zigbee/ZWave controller.  Having
dedicated taints for those roles is much more clear.
2025-07-29 21:39:21 -05:00
Dustin 8b492d059d xactmon: Pin to x86_64 nodes
There are no ARM builds of the `xactmon` components.
2025-07-29 21:38:06 -05:00
Dustin 812b09626f cert-manager: Drop chmod777.sh certificate
This site now obtains its own certificate using Apache _mod_md_.
2025-07-28 18:59:06 -05:00
Dustin 32666aa628 h-a: Schedule Piper, Whisper, Mosquitto with HA
Using pod affinity rules, we can schedule the ancillary processes for
Home Assistant to run on the same node as the main server.
2025-07-27 18:39:55 -05:00
Dustin 7b440c44ec h-a: Prefer running on a Raspberry Pi
Now that we have Raspberry Pi CM4 worker nodes, let's configure Home
Assistant to run on one, since it's pretty much designed to.
2025-07-27 18:35:07 -05:00
Dustin 6d2aa9c391 20125: Set log level
Only errors are logged by default, which is less than helpful when
troubleshooting a running but apparently misbehaving application...
2025-07-27 18:20:27 -05:00
Dustin b989a7898e 20125: Pin to amd64 nodes
There is no ARM build of the 20125 `status-server`, so we have to pin
the pod to amd64 nodes to prevent it from being scheduled on a Raspberry
Pi.
2025-07-27 18:19:58 -05:00
Dustin 921fadc44b 20125: Fix website URL anchors
As it turns out, it's not possible to reuse a YAML anchor.  At least in
Rust's `serde_yaml`, only the final definition is used.  All references,
even those that appear before the final definition, use the same
definition.  Thus, each application that refers to its own URL in its
match criteria needs a unique anchor.
2025-07-27 18:16:30 -05:00
Dustin 4dc21e6179 sshca: Add machine IDs for CM4 cluster nodes
* _ctrl-2ed83d.k8s.pyrocufflink.black_
* _node-6a3f8.k8s.pyrocufflink.black_
* _node-6ed191.k8s.pyrocufflink.black_
2025-07-27 17:42:43 -05:00
Dustin 972831d15f 20125: Fix alert selector for Jellyfin
Jellyfin is not scraped by the Blackbox exporter, but rather exposes its
own metrics.
2025-07-27 17:40:54 -05:00
Dustin 38ee60e099 v-m: Add alerts for Firefly, Paperless, phpipam
_Firefly III_ and _phpipam_ don't export any Prometheus metrics, so we
have to scrape them via the Blackbox Exporter.

Paperless-ngx only exposes metrics via Flower, but since it runs in the
same container as the main application, we can assume that if the former
is unavailable, the latter is as well.
2025-07-27 17:39:28 -05:00
Dustin fac4b92b71 cert-manager: Drop hatch.chat certificate
The _hatch.chat_ Matrix server has been gone for quite some time.
2025-07-23 11:59:28 -05:00
Dustin 81f8c58816 cert-manager: Drop tabitha.biz certificate
This site now obtains its own certificate using Apache _mod_md_.
2025-07-23 11:41:09 -05:00
Dustin 592ff3ce9e cert-manager: Drop apps.d.x certificate
This site now obtains its own certificate using Apache _mod_md_.
2025-07-23 11:29:34 -05:00
Dustin 36015084c8 ansible: Allow host-provisioner to read root CA
The Kubernetes root CA certificate is stored in a ConfigMap named
`kube-root-ca.crt` in every namespace.  The _host-provisioner_ needs to
be able to read this ConfigMap in order to prepare control plane nodes,
as it is used by HAProxy to check the health of the API servers running
on each node.
2025-07-23 10:50:24 -05:00
Dustin 484c17c1d5 authelia: Add address, phone scopes for Jenkins
Not sure why suddenly these need to be granted, but without them, I
cannot log in to Jenkins.
2025-07-22 15:26:29 -05:00
Dustin e845e66262 restic: pin to 0.18.0
Let's keep the version of `restic` used by the prune job in sync with
the latest version in Fedora.
2025-07-21 18:58:57 -05:00
Dustin 717f9244e7 kubelet-csr-approver: Initial commit
The [kubelet-csr-approver][0] is a controller that automatically approves
CSRs for Kublets that match certain criteria.  I've had it deployed in
the cluster for a while, but apparently never committed the resources.
These manifest files are taken from the [k8s deployment example][1] in
the upstream repository.

[0]: https://github.com/postfinance/kubelet-csr-approver
[1]: https://github.com/postfinance/kubelet-csr-approver/tree/v1.2.10/deploy/k8s
2025-07-21 18:49:44 -05:00
Dustin da2b1e60cd autoscaler: Set imagePullPolicy: IfNotPresent
We don't want to pull public container images that already exist.  This
creates prevents pods from starting if there is any connectivity issue
with the upstream registry.
2025-07-21 17:17:16 -05:00
Dustin 810134e9bc authelia: Set imagePullPolicy: IfNotPresent
We don't want to pull public container images that already exist.  This
creates prevents pods from starting if there is any connectivity issue
with the upstream registry.
2025-07-21 17:16:32 -05:00
Dustin 7fd613ccaf ara: Set imagePullPolicy: IfNotPresent
We don't want to pull public container images that already exist.  This
creates prevents pods from starting if there is any connectivity issue
with the upstream registry.
2025-07-21 17:14:06 -05:00
Dustin 68c7e0d6cc argocd: Set imagePullPolicy: IfNotPresent
We don't want to pull public container images that already exist.  This
creates prevents pods from starting if there is any connectivity issue
with the upstream registry.
2025-07-21 15:07:01 -05:00
Dustin 5da80c6a55 ntfy: Set imagePullPolicy: IfNotPresent
We don't want to pull public container images that already exist.  This
creates prevents pods from starting if there is any connectivity issue
with the upstream registry.
2025-07-21 15:07:01 -05:00
Dustin 32132842be firefly-iii: Set imagePullPolicy: IfNotPresent
We don't want to pull public container images that already exist.  This
creates prevents pods from starting if there is any connectivity issue
with the upstream registry.
2025-07-21 15:07:01 -05:00
Dustin 0822afe0b3 kitchen: Round weather metrics
Home Assistant has started sending the full sensor values for weather
metrics to Prometheus, even though their precision is way beyond their
accuracy.  We don't need to see 4+ decimal points for these on the
Kitchen display, so let's round the values when we query.
2025-07-21 14:40:35 -05:00
Dustin e51878fa92 ansible: Allow h-p to update scrape-collectd CM
The `scrape-collectd` ConfigMap in the `default` namespace is used by
Victoria Metrics to identif the hosts from which it should scrape
collectd metrics.  When deploying new machines that are _not_ part of
the Kubernetes cluster, we need to explicitly add them to this list.
The _host-provisioner_ can do this with an Ansible task, but it needs
the appropriate permissions to do so.
2025-07-21 12:24:00 -05:00
Dustin dbbe23aaa5 cert-manager: Add role for Jenkins to access certs
Ansible playbook running as Jenkins jobs need to be able to access the
Secret resources containing certificates issued by _cert-manager_ in
order to install them on managed nodes.  Although not all jobs do this
yet, eventually, the _cert-exporter_ will no longer be necessary, as the
_certs.git_ repository will not be used anymore.
2025-07-21 12:24:00 -05:00
Dustin d48dabca5b Merge remote-tracking branch 'refs/remotes/origin/master' 2025-07-21 12:02:44 -05:00
Dustin 16dec1cdec ssh-host-keys: Do not specify a namespace
We don't want to hard-code a namespace for the `ssh-known-hosts`
ConfigMap because that makes it less useful for other projects besides
Jenkins.  Instead, we omit the namespace specification and allow
consumers to specify their own.

The _jenkins_ project doesn't have a default namespace, since it
specifies resources in the `jenkins` and `jenkins-jobs` namespaces, we
need to create a sub-project to set the namespace for the
`ssh-known-hosts` ConfigMap.
2025-07-21 11:47:39 -05:00
Dustin 959959155c Merge pull request 'home-assistant: Update to 2025.7.1' (#69) from updatebot/home-assistant into master
Reviewed-on: #69
2025-07-16 21:55:57 +00:00
Dustin b36c132364 Merge pull request 'ntfy: Update to 2.13.0' (#72) from updatebot/ntfy into master
Reviewed-on: #72
2025-07-16 21:49:29 +00:00
Dustin dc31ae1cae Merge pull request 'tika: Update to 3.2.1.0' (#71) from updatebot/paperless-ngx into master
Reviewed-on: #71
2025-07-16 21:45:03 +00:00
bot 05048cbaa1 ntfy: Update to 2.13.0 2025-07-12 11:32:13 +00:00
bot 434d420e28 tika: Update to 3.2.1.0 2025-07-12 11:32:11 +00:00
bot bab05add07 mosquitto: Update to 2.0.22 2025-07-12 11:32:06 +00:00
bot 467365922a zwavejs2mqtt: Update to 10.9.0 2025-07-12 11:32:06 +00:00
bot 0815350de8 zigbee2mqtt: Update to 2.5.1 2025-07-12 11:32:06 +00:00
bot d48ebb4292 piper: Update to 1.6.2 2025-07-12 11:32:06 +00:00
bot 7ddaf5bda8 home-assistant: Update to 2025.7.1 2025-07-12 11:32:05 +00:00
Dustin 9645abef5e home-assistant: Pull Zigbee/ZWave images from ghcr
Getting around Docker Hub rate limiting
2025-07-07 08:46:04 -05:00
Dustin 8491d2ded7 v-m: Switch to quay.io for container images
Docker Hub has blocked ("rate limited") my IP address.  Moving as much
as I can to use images from other sources.  Hopefully they'll unblock me
soon and I can deploy a caching proxy.
2025-07-07 08:43:20 -05:00
Dustin ff1e13a5d7 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-07-07 08:43:10 -05:00
Dustin 093e909475 v-m/scrape: Scrape Victoria Logs 2025-07-06 15:20:16 -05:00
Dustin 61460e56e9 20125: Mark MinIO backups alerts as system-wide
Backups failing may not prevent services from operating correctly, but
we do want to have visibility into that.
2025-07-06 12:27:07 -05:00
Dustin 9d18173b3e Merge pull request 'firefly-iii: Update to 6.2.20' (#70) from updatebot/firefly-iii into master
Reviewed-on: #70
2025-07-05 16:08:07 +00:00
bot 52f999fe93 firefly-iii: Update to 6.2.20 2025-07-05 11:32:18 +00:00
Dustin cc83a5115a v-m/scrape: Scrape MinIO metrics 2025-07-02 10:29:53 -05:00
Dustin 370c8486fa authelia: Set claims policy for MinIO
MinIO console needs access to the *groups* scope in order to assign the
correct permissions to users as they log in.
2025-07-01 11:54:01 -05:00
Dustin 6e2cbeb102 ansible: Add service account for host-provisioner
The _k8s-worker_ Ansible role in the configuration policy now uses the
Kubernetes API to create bootstrap tokens for adding worker nodes to the
cluster.  For this to work, the pod running the host-provisioner must be
associated with a service account that has the correct permissions to
create secrets and access the `cluster-info` ConfigMap.
2025-06-30 16:16:28 -05:00
Dustin 9d09b9584b Merge pull request 'home-assistant: Update to 2025.6.3' (#67) from updatebot/home-assistant into master
Reviewed-on: #67
2025-06-28 14:27:15 +00:00
Dustin e46798b725 Merge pull request 'firefly-iii: Update to 6.2.19' (#68) from updatebot/firefly-iii into master
Reviewed-on: #68
2025-06-28 14:27:02 +00:00
bot bcd53d2819 firefly-iii: Update to 6.2.19 2025-06-28 11:32:13 +00:00
bot 839b8dbcdc home-assistant: Update to 2025.6.3 2025-06-28 11:32:07 +00:00
Dustin 404137c4c8 h-a/whisper: Set writable cache dir for HF models
Whisper now needs a writable location for downloading models from
Hugging Face Hub.  The default location is `~/.cache/huggingface/hub`,
but this is not writable in our container.  The path can be controlled
via one of several environment variables, but we're setting `HF_HOME` as
it is sets the top level directory for several related paths.
2025-06-21 14:22:42 -05:00
Dustin 8e38813d83 Merge pull request 'home-assistant: Update to 2025.4.4' (#61) from updatebot/home-assistant into master
Reviewed-on: #61
2025-06-21 19:15:14 +00:00
Dustin 7d7199ee10 Merge pull request 'paperless-ngx: Update to 2.17.1' (#66) from updatebot/paperless-ngx into master
Reviewed-on: #66
2025-06-21 19:01:39 +00:00
Dustin 8a5e8ed720 Merge branch 'xactmon-firefly-token' 2025-06-21 14:00:45 -05:00
Dustin fdb4bdb23d Merge branch 'unifi' 2025-06-21 14:00:38 -05:00
Dustin 1ce3e7ef43 Merge branch 'xactmon-fix-chase' 2025-06-21 14:00:35 -05:00
Dustin 75edfb74cb v-m/scrape: Increase timeout for k8s job
Scraping metrics from the Kubernetes API server has started taking 20+
seconds recondly.  Until I figure out the underlying cause, I'm
increasing the scrape timeout so that the _vmagent_ doesn't give up and
report the API server as "down."
2025-06-21 13:55:23 -05:00
Dustin 4106038fe9 cert-manager: Use recursive resolver for checks
I've completely blocked all outgoing unencrypted DNS traffic at the
firewall now, which prevents _cert-manager_ from using its default
behavior of using the authoritative name servers for its managed domains
to check poll for ACME challenge DNS TXT record availability.
Fortunately, it has an option to use a recursive resolver (i.e. the
network-provided DNS server) instead.
2025-06-21 13:55:23 -05:00
Dustin f4b0d43d25 Merge pull request 'firefly-iii: Update to 6.2.18' (#65) from updatebot/firefly-iii into master
Reviewed-on: #65
2025-06-21 18:36:44 +00:00
bot 6bbd5b89cd gotenberg: Update to 8.21.1 2025-06-21 11:32:18 +00:00
bot 4744e663f1 paperless-ngx: Update to 2.17.1 2025-06-21 11:32:18 +00:00
bot eb5d31edca firefly-iii: Update to 6.2.18 2025-06-21 11:32:15 +00:00
bot 555ce06992 zwavejs2mqtt: Update to 10.7.0 2025-06-21 11:32:12 +00:00
bot a391338cfa zigbee2mqtt: Update to 2.4.0 2025-06-21 11:32:12 +00:00
bot e1e8f86c92 piper: Update to 1.5.4 2025-06-21 11:32:12 +00:00
bot de5d3bf87c whisper: Update to 2.5.0 2025-06-21 11:32:12 +00:00
bot c9d3302be1 home-assistant: Update to 2025.6.1 2025-06-21 11:32:11 +00:00
Dustin 25644150fa Merge pull request 'firefly-iii: Update to 6.2.10' (#60) from updatebot/firefly-iii into master
Reviewed-on: #60
2025-06-15 15:35:17 +00:00
Dustin cd8a8b7002 Merge pull request 'paperless-ngx: Update to 2.16.3' (#64) from updatebot/paperless-ngx into master
Reviewed-on: #64
2025-06-15 14:54:10 +00:00
Dustin 50f0f83dcc Merge pull request 'ntfy: Update to 2.12.0' (#62) from updatebot/ntfy into master
Reviewed-on: #62
2025-06-14 21:58:39 +00:00
Dustin abcd007948 home-assistant: Deploy mqtt2vl
`mqtt2vl` is a relatively simple service I developed to read log
messages from an MQTT topic (i.e. those published by ESPHome devices)
and stream them to Victoria Logs over HTTPS.
2025-06-14 16:55:12 -05:00
bot 4d9598af73 ntfy: Update to 2.12.0 2025-06-14 11:32:25 +00:00
bot 81e58e85d0 tika: Update to 3.2.0.0 2025-06-14 11:32:23 +00:00
bot 914dfccb8f paperless-ngx: Update to 2.16.3 2025-06-14 11:32:23 +00:00
bot 86abf880d6 firefly-iii: Update to 6.2.17 2025-06-14 11:32:14 +00:00
Dustin e0af6e0549 argocd/apps/grafana: Enable auto sync 2025-06-05 07:09:00 -05:00
Dustin 9b1a5ef14f grafana: Add Victoria Logs data source 2025-06-05 07:07:55 -05:00
Dustin eb754d9112 grafana: Update to 11.5.5
The legacy alerting feature (which we never used) has been deprecated
for a long time and removed in Grafana 11.  The corresponding
configuration block must be removed from the config file or Grafana will
not start.
2025-06-05 07:06:40 -05:00
Dustin 721d82eac3 paperless-ngx: Make /run writable
The latest version of Paperless-ngx needs a writable `/run` or it will
not even start.
2025-06-05 07:00:59 -05:00
Dustin 92cf2c1b77 authelia: Update config for 4.39
Authelia made breaking changes to the OIDC issuer configuration in 4.39,
specifically around what claims are present in identity tokens.  Without
a claims policy set, clients will _not_ get the correct claims, which
breaks authentication and authorization in many cases (including
Kubernetes).

While I was fixing that, I went ahead and fixed a few of the other
deprecation warnings.  There are still two that show up at startup, but
fixing them will be a bit more involved, it seems.
2025-06-05 07:00:50 -05:00
Dustin 85236243c2 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-06-04 07:02:51 -05:00
Dustin fb1ef70dd3 Merge pull request 'authelia: Update to 4.39.1' (#59) from updatebot/authelia into master
Reviewed-on: #59
2025-06-03 23:58:31 +00:00
Dustin 25da978286 Merge pull request 'gotenberg: Update to 8.18.0' (#58) from updatebot/paperless-ngx into master
Reviewed-on: #58
2025-06-03 23:58:12 +00:00
Dustin 1c936943a0 Merge pull request 'vaultwarden: Update to 1.34.1' (#63) from updatebot/vaultwarden into master
Reviewed-on: #63
2025-06-03 23:54:14 +00:00
bot f45a8de0c1 vaultwarden: Update to 1.34.1 2025-05-31 11:32:18 +00:00
bot d27934a211 authelia: Update to 4.39.4 2025-05-31 11:32:17 +00:00
bot 1f02ad70da gotenberg: Update to 8.21.0 2025-05-31 11:32:12 +00:00
bot 8e1ac08d15 paperless-ngx: Update to 2.16.2 2025-05-31 11:32:12 +00:00
Dustin eb912adb6d xactmon: Renew Firefly-III API token 2025-05-04 14:39:39 +00:00
Dustin 43d5d7f39e home-assistant: Run as root in user namespace
Beginning with Home Assistant 2024.12, it is no longer possible to use
custom integrations if the container is running as an unprivileged user.
Fortunately, it can be "tricked" by running as root in an unprivileged
user namespace.

https://github.com/blakeblackshear/frigate-hass-integration/issues/762
https://github.com/home-assistant/core/issues/132336
2025-04-20 17:04:17 -05:00
Dustin aebdbc2e12 Merge pull request 'home-assistant: Update to 2025.3.4' (#57) from updatebot/home-assistant into master
Reviewed-on: #57
2025-04-20 21:31:11 +00:00
bot e800d302ea zwavejs2mqtt: Update to 10.2.0 2025-04-19 11:32:07 +00:00
bot 8957bfc1f9 zigbee2mqtt: Update to 2.2.1 2025-04-19 11:32:07 +00:00
bot 54b287d85d home-assistant: Update to 2025.4.3 2025-04-19 11:32:06 +00:00
Dustin cf9eae14b4 restic: Add restic-prune CronJob
This CronJob schedules a periodic run of `restic forget`, which deletes
snapshots according to the specified retention period (14 daily, 4
weekly, 12 monthly).

This task used to run on my workstation, scheduled by a systemd timer
unit.  I've kept the same schedule and retention period as before.  Now,
instead of relying on my PC to be on and awake, the cleanup will occur
more regularly.  There's also the added benefit of getting the logs into
Loki.
2025-04-01 19:36:10 -05:00
Dustin 5c819ef120 paperless-ngx: Work around PDF rendering errors
Occasionally, some documents may have odd rendering errors that
prevent the archival process from working correctly.  I'm less concerned
about the archive document than simply having a centralized storage for
paperwork, so enabling this "continue on soft render error" feature is
appropriate.  As far as I can tell, it has no visible effect for the
documents that could not be imported at all without it.
2025-03-31 06:16:41 -05:00
Dustin 52094da8fd v-m/scrape: Remove unifi3, Zincati
*unifi3.pyrocufflink.blue* has been replaced by
*unifi-nuptials.host.pyrocufflink.black*.  The former was the last
Fedora CoreOS machine in use, so the entire Zincati scrape job is no
longer needed.
2025-03-29 08:10:50 -05:00
Dustin 37890e32a1 xactmon/rules: Fix Chase regex for >$1k
Never had a transaction of over $1000 before!  Chase's e-mail messages
have a thousands separator that I wasn't expecting.
2025-03-18 19:27:37 +00:00
Dustin 7c6b6f4ca4 Merge pull request 'firefly-iii: Update to 6.2.0' (#46) from updatebot/firefly-iii into master
Reviewed-on: #46
2025-03-15 13:07:40 +00:00
Dustin a5ce333c74 Merge pull request 'gotenberg: Update to 8.17.3' (#56) from updatebot/paperless-ngx into master
Reviewed-on: #56
2025-03-15 13:06:39 +00:00
Dustin cce7e56d02 Merge pull request 'zwavejs2mqtt: Update to 9.31.0' (#55) from updatebot/home-assistant into master
Reviewed-on: #55
2025-03-15 13:00:29 +00:00
bot ec996f5872 gotenberg: Update to 8.17.3 2025-03-15 11:32:13 +00:00
bot bb87deb888 firefly-iii: Update to 6.2.9 2025-03-15 11:32:11 +00:00
bot 0762238900 mosquitto: Update to 2.0.21 2025-03-15 11:32:09 +00:00
bot 6aa0b21848 zwavejs2mqtt: Update to 9.33.0 2025-03-15 11:32:09 +00:00
bot 05ebb147c1 zigbee2mqtt: Update to 2.1.3 2025-03-15 11:32:09 +00:00
bot f907a31650 home-assistant: Update to 2025.3.3 2025-03-15 11:32:08 +00:00
Dustin 8470af0558 receipts: Deploy Receipts management tool
This is a custom-built application for managing purchase receipts.  It
integrates with Firefly III to fill some of the gaps that `xactmon`
cannot handle, such as restaurant bills with tips, gas station
purchases, purchases with the HSA debit card, refunds, and deposits.

Photos of receipts can be taken directly within the application using
the User Media Web API, or uploaded as existing files.  Each photo is
associated with transaction data, including date, vendor, amount, and
general notes.  These data are also synchronized with Firefly whenever
possible.
2025-03-13 20:26:11 -05:00
Dustin b75d83cd32 sshca: Do not sign certs for root
We no longer need *root* in the list of authorized principals for user
certificates issued by SSHCA.
2025-03-04 19:23:49 -06:00
Dustin 8f5129cbef dch-webhooks: Enable test hosts in provisioner
By default, the _pyrocufflink_ Ansible inventory plugin ignores VMs
whose names begin with `test-`.  This prevents Jenkins from failing to
apply policy to machines that it should not be managing.  The host
provisioner job, though, should apply policy to those machines, so we
need to disable that filter.
2025-03-04 19:23:49 -06:00
Dustin 33da018988 Merge pull request 'authelia: Update to 4.38.19' (#54) from updatebot/authelia into master
Reviewed-on: #54
2025-02-23 22:33:08 +00:00
Dustin efc53fd7f0 Merge pull request 'home-assistant: Update to 2025.2.5' (#53) from updatebot/home-assistant into master
Reviewed-on: #53
2025-02-23 22:22:56 +00:00
bot 46b3e57101 authelia: Update to 4.38.19 2025-02-22 12:32:16 +00:00
bot 00502a08cc home-assistant: Update to 2025.2.5 2025-02-22 12:32:08 +00:00
Dustin f10879fbf6 Merge pull request 'home-assistant: Update to 2025.2.4' (#50) from updatebot/home-assistant into master
Reviewed-on: #50
2025-02-15 17:54:29 +00:00
Dustin 383b26401b Merge pull request 'gotenberg: Update to 8.17.1' (#51) from updatebot/paperless-ngx into master
Reviewed-on: #51
2025-02-15 13:02:07 +00:00
Dustin e17f95bcfc Merge pull request 'vaultwarden: Update to 1.33.2' (#52) from updatebot/vaultwarden into master
Reviewed-on: #52
2025-02-15 13:01:34 +00:00
bot 037bb7ad23 vaultwarden: Update to 1.33.2 2025-02-15 12:32:15 +00:00
bot 025c4f7a5a gotenberg: Update to 8.17.1 2025-02-15 12:32:12 +00:00
bot 0fb4654e6c home-assistant: Update to 2025.2.4 2025-02-15 12:32:05 +00:00
Dustin 7da76d0615 cert-manager: Update to v1.16.4
Fixes for Cloudflare DNS API changes.
2025-02-14 18:27:31 -06:00
Dustin f9a315eba5 Merge pull request 'zwavejs2mqtt: Update to 9.30.1' (#45) from updatebot/home-assistant into master
Reviewed-on: #45
2025-02-10 23:49:17 +00:00
Dustin cf8dff83eb Merge pull request 'paperless-ngx: Update to 2.14.7' (#47) from updatebot/paperless-ngx into master
Reviewed-on: #47
2025-02-09 15:38:22 +00:00
Dustin 3abecae4d8 Merge pull request 'vaultwarden: Update to 1.33.1' (#49) from updatebot/vaultwarden into master
Reviewed-on: #49
2025-02-09 01:53:19 +00:00
Dustin 3255edc7b6 rabbitmq: Configure dch-webhooks/host-provisioner
The *dch-webhooks* user is used by *dch-webhooks* in order to publish
host information when a new machine triggers its _POST /host/online_
webhook.  It therefore needs to be able to write to the
_host-provisioner_ queue (via the default exchange).

The *host-provisioner* user is used by the corresponding consumer to
receive the host information and initiate the provisioning process.
2025-02-08 16:59:26 -06:00
Dustin bed5ed5767 dch-webhooks: Enable host provisioning feature
The *dch-webhooks* server now has a _POST /host/online_ hook that can
be triggered by a new machine when it first comes online. This hook
starts an automatic provisioning process by creating a Kubernetes Job
to run Ansible and publishing information about the host to provision
via AMQP.  Thus, the server now needs access to the Kubernetes API in
order to create the Job and access to RabbitMQ in order to publish the
task parameters.
2025-02-08 16:59:26 -06:00
Dustin 4d11a60e62 dch-root-ca: Disable hash name suffix
The contents of the DCH Root CA will not change, so it does not make
sense to enable the hash suffix feature for this ConfigMap.  Without it,
the ConfigMap name is predictable and can be used outside of a Kustomize
project.
2025-02-08 16:59:17 -06:00
Dustin edec79aaae ssh-known-hosts: Move ConfigMap to its own project
This will allow multiple projects to have a ConfigMap with the same
`ssh_known_hosts` contents without duplicating the source file in the
repository.
2025-02-08 11:56:34 -06:00
Dustin 28e120ddbd updatebot: Correct vaultwarden project name
Updatebot kept trying to "update" Authelia with the latest version of
Vaultwarden 🤦🏻‍♂️
2025-02-08 10:46:04 -06:00
bot 58d2f94842 vaultwarden: Update to 1.33.1 2025-02-08 15:52:46 +00:00
bot 983bf4808d tika: Update to 3.1.0.0 2025-02-08 15:52:44 +00:00
bot ffdcf6bd73 gotenberg: Update to 8.17.0 2025-02-08 15:52:44 +00:00
bot 6bee9847fc paperless-ngx: Update to 2.14.7 2025-02-08 15:52:44 +00:00
bot 0e1eefc13f zwavejs2mqtt: Update to 9.30.1 2025-02-08 15:52:40 +00:00
bot 4c0efc6a87 zigbee2mqtt: Update to 2.1.1 2025-02-08 15:52:39 +00:00
bot d16f27394c home-assistant: Update to 2025.2.1 2025-02-08 15:52:38 +00:00
Dustin dc835ddc9d v-m/alerts: Fix PostgreSQL WAL archive failed alert
The `pg_stat_archiver_failed_count` metric is a counter, so once a WAL
archival has failed, it will increase and never return to `0`.  To
ensure the alert is resolved once the WAL archival process recovers, we
need to use the `increase` function to turn it into a gauge.  Finally,
we aggregate that gauge with `max_over_time` to keep the alert from
flapping if the WAL archive occurs less frequently than the scrape
interval.
2025-02-05 10:42:35 -06:00
Dustin f637feba16 updatebot: Fix tag format for Vaultwarden
We're using the Alpine variant of the Vaultwarden container images,
since the default variant is significantly larger and we do not need any
of the extra stuff it includes.
2025-02-01 18:29:54 -06:00
Dustin 6da330f2be v-m/scrape: Remove k8s SD config for Zincati
There are no more Kubernetes nodes running Fedora CoreOS.
2025-02-01 18:16:10 -06:00
Dustin 11a0f84db7 v-m/scrape: Remove websites job
Websites are being scraped by the `vmagent` on the OVH VPS.
2025-02-01 18:16:10 -06:00
Dustin 79995801e2 jenkins: ssh_known_hosts: Add OVH VPS host key 2025-02-01 18:16:10 -06:00
Dustin 759d8f112f ansible: Deploy ARA
[ARA Records Ansible][0] is a results storage system for Ansible.  It
provides a convenient UI for tracking Ansible playbooks and tasks.  The
data are populated by an Ansible callback plugin.

ARA is a fairly simple Python+Django application.  It needs a database
to store Ansible results, so we've connected it to the main PostgreSQL
database and configured it to connect and authenticate using mTLS.

Rather than mess with managing and distributing a static password for
ARA clients, I've configured Autheliad to allow anonymous access to
post data to the ARA API from within the private network or the
Kubernetes cluster.  Access to the web UI does require authentication.

[0]: https://ara.recordsansible.org/
2025-02-01 18:16:10 -06:00
Dustin 32175156ac sshca: Add machine ID for node-474c83.k8s.p.bk 2025-02-01 18:16:10 -06:00
Dustin a87b53e3ac v-m: Add alert for Frigate camera no video
At some point this week, the front porch camera stopped sending video.
I'm not sure exactly what happened to it, but Frigate kept logging
"Unable to read frames from ffmpeg process."  I power-cycled the camera,
which resolved the issue.

Unfortunately, no alerts were generated about this situation.  Home
Assistant did not consider the camera entity unavailable, presumably
because Frigate was still reporting stats about it.  Thus, I missed
several important notifications.  To avoid this in the future, I have
enabled the "Camera FPS" sensors for all of the cameras in Home
Assistant, and added this alert to trigger when the reported framerate
is 0.

I really also need to get alerts for log events configured, as that
would also indicated there was an issue.
2025-02-01 18:16:10 -06:00
Dustin 5065e61a2d Merge pull request 'home-assistant: Update to 2025.1.4' (#43) from updatebot/home-assistant into master
Reviewed-on: #43
2025-01-25 14:44:49 +00:00
Dustin 39298e9fea Merge pull request 'paperless-ngx: Update to 2.14.5' (#44) from updatebot/paperless-ngx into master
Reviewed-on: #44
2025-01-25 14:44:41 +00:00
bot b32751bf28 paperless-ngx: Update to 2.14.5 2025-01-25 12:32:13 +00:00
bot 4ce258b00c home-assistant: Update to 2025.1.4 2025-01-25 12:32:06 +00:00
Dustin 294c0230bf home-assistant: Update IP kitchen kiosk IP address
I got a new 2GB Raspberry Pi 4 Model B for the kitchen.  That way, I can
use the 4GB one for something that needs more memory.
2025-01-23 18:00:17 -06:00
Dustin 183bb28c12 authelia: Allow anonymous access to vminsert
This way we can have push-based metrics without requiring any
authentication.
2025-01-19 09:47:28 -06:00
Dustin ce7d90d704 Merge pull request 'zwavejs2mqtt: Update to 9.29.1' (#41) from updatebot/home-assistant into master
Reviewed-on: #41
2025-01-18 15:46:05 +00:00
Dustin 91f0432061 Merge pull request 'paperless-ngx: Update to 2.14.3' (#42) from updatebot/paperless-ngx into master
Reviewed-on: #42
2025-01-18 15:45:52 +00:00
bot 5fb6d70f59 paperless-ngx: Update to 2.14.3 2025-01-18 12:32:13 +00:00
bot 511a9df619 zwavejs2mqtt: Update to 9.29.1 2025-01-18 12:32:08 +00:00
Dustin e426bcf550 Merge pull request 'gotenberg: Update to 8.15.2' (#38) from updatebot/paperless-ngx into master
Reviewed-on: #38
2025-01-11 16:27:50 +00:00
Dustin 509c44d9cc Merge pull request 'authelia: Update to 4.38.18' (#40) from updatebot/authelia into master
Reviewed-on: #40
2025-01-11 16:27:21 +00:00
Dustin 4ac1bab968 h-a: zigbee2m: Add dialout supplemental group
Zigbee2MQTT needs to be able to read and write to the serial device for
the ConBee II USB controller.  I'm not exactly sure what changed, or how
it was able to access it before the recent update.

The _dialout_ group has GID 18 on Fedora.
2025-01-11 10:10:44 -06:00
Dustin 1674bc3b89 Merge pull request 'home-assistant: Update to 2025.1.0' (#39) from updatebot/home-assistant into master
Reviewed-on: #39
2025-01-11 15:57:26 +00:00
bot 4a197bf91a authelia: Update to 4.38.18 2025-01-11 12:32:12 +00:00
bot 07ffcd0bc5 gotenberg: Update to 8.15.3 2025-01-11 12:32:11 +00:00
bot e567c34df5 zigbee2mqtt: Update to 2.0.0 2025-01-11 12:32:06 +00:00
bot a8528302ee home-assistant: Update to 2025.1.2 2025-01-11 12:32:05 +00:00
Dustin 94be854bd7 vaultwarden: Deploy, migrate Vaultwarden
Vaultwarden requires basically no configuration anymore.  Older versions
needed some environment variables for configuring the WebSocket server,
but as of 1.31, WebSockets are handled by the same server as HTTP, so
even that is not necessary now.  The only other option that could
potentially be useful is `ADMIN_TOKEN`, but it's optional.  For added
security, we can leave it unset, which disables the administration
console; we can set it later if/when we actually need that feature.

Migrating data from the old server was pretty simple.  The database is
pretty small, and even the attachments and site icons don't take up much
space.  All-in-all, there was only about 20 MB to move, so the copy only
took a few seconds.

Aside from moving the Vaultwarden server itself, we will also need to
adjust the HAProxy configuration to proxy requests to the Kubernetes
ingress controller.
2025-01-10 20:05:18 -06:00
Dustin 1392a7c181 jenkins: Add storage for Gentoo Portage/binpkgs
Jenkins that build Gentoo-based systems, like Aimee OS, need a
persistent storage volume for the Gentoo ebuild repository. The Job
initially populates the repository using `emerge-webrsync`, and then the
CronJob keeps it up-to-date by running `emaint sync` daily.

In addition to the Portage repository, we also need a volume to store
built binary packages.  Jenkins job pods can mount this volume to make
binary packages they build available for subsequent runs.

Both of these volumes are exposed to use cases outside the cluster using
`rsync` in daemon mode.  This can be useful for e.g. local builds.
2025-01-09 20:15:46 -06:00
Dustin 75e6f7ee16 home-assistant: Add trusted user for Kitchen kiosk
The Raspberry Pi in the kitchen now has Firefox installed so we can use
it to control Home Assistant.  By listing its IP address as a trusted
network, and assigning it a trusted user, it can access the Home
Assistant UI without anyone having to type a password.  This is
particularly important since there's no keyboard (not even an on-screen
virtual one).

Moving the `trusted_networks` auth provider _before_ the `homeassistant`
provider changes the login screen to show a "log in as ..." dialog by
default on trusted devices.  It does not affect other devices at all,
but it does make the initial login a bit easier on kiosks.
2025-01-04 07:19:39 -06:00
Dustin 252dcfedc8 sshca: Add machine ID for ctrl-pi-spellbind 2024-12-28 10:38:26 -06:00
Dustin 6883ab41bd Merge remote-tracking branch 'refs/remotes/origin/master' 2024-12-21 20:23:42 -06:00
Dustin 8374e1e28b Merge remote-tracking branch 'refs/remotes/origin/master' 2024-12-21 20:23:25 -06:00
Dustin a74f7f64ad Merge remote-tracking branch 'refs/remotes/origin/master' 2024-12-21 20:22:36 -06:00
Dustin 60f88c6960 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-12-21 20:21:04 -06:00
Dustin 21dcd853c4 Merge pull request 'home-assistant: Update to 2024.11.3' (#35) from updatebot/home-assistant into master
Reviewed-on: #35
2024-12-21 20:27:26 +00:00
Dustin b9d69ec0a3 v-m/alerts: Ignore missing backups from Toad, Luma
Toad and Luma can go offline for several days at a time if I don't use
them.  I don't need an alert telling me this.
2024-12-21 12:23:19 -06:00
Dustin a03d63841d v-m/alerts: Fire paperless email alert after 12h
We don't need a notification about paperless not scheduling email tasks
every time there is a gap in the metric.  This can happen in some
innocuous situations like when the pod restarts or if there is a brief
disruption of service.  Using the `absent_over_time` function with a
range vector, we can have the alert fire only if there have been no
email tasks scheduled within the last 12 hours.
2024-12-21 12:17:45 -06:00
Dustin d04c18cfcd v-m/alerts: Remove 'no file changes' alert
It turns out this alert is not very useful, and indeed quite annoying.
Many servers can go for days or even weeks with no changes, which is
completely normal.
2024-12-21 12:14:11 -06:00
Dustin 6e15b11f73 Merge branch 'fix-nextcloud-alert' 2024-12-21 11:58:41 -06:00
Dustin db37e5a691 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-12-21 11:58:07 -06:00
Dustin 7a9adc642c Merge pull request 'firefly-iii: Update to 6.1.24' (#37) from updatebot/firefly-iii into master
Reviewed-on: #37
2024-12-21 17:39:21 +00:00
Dustin 93e42421e6 Merge pull request 'gotenberg: Update to 8.14.1' (#36) from updatebot/paperless-ngx into master
Reviewed-on: #36
2024-12-21 17:38:50 +00:00
bot a79668dcf1 gotenberg: Update to 8.14.1 2024-12-21 12:32:10 +00:00
bot 1c4b5e19a4 firefly-iii: Update to 6.1.25 2024-12-21 12:32:08 +00:00
bot 2691b58c05 zwavejs2mqtt: Update to 9.29.0 2024-12-21 12:32:04 +00:00
bot 50459e111e zigbee2mqtt: Update to 1.42.0 2024-12-21 12:32:04 +00:00
bot 387b7d120e whisper: Update to 2.4.0 2024-12-21 12:32:04 +00:00
bot 1768778b44 home-assistant: Update to 2024.12.5 2024-12-21 12:32:03 +00:00
Dustin 2b6830f131 cert-manager: Configure ACME DNS.01 for dch-ca
Since transitioning to externalIPs for TCP services, it is no longer
possible to use the HTTP.01 ACME challenge to issue certificates for
services hosted in the cluster, because the ingress controller does not
listen on those addresses.  Thus, we have to switch to using the DNS.01
challenge.  I had avoided using it before because of the complexity of
managing dynamic DNS records with the Samba AD server, but this was
actually pretty to work around.  I created a new DNS zone on the
firewall specifically for ACME challenges.  Names in the AD-managed zone
have CNAME records for their corresponding *_acme-challenge* labels
pointing to this new zone.  The new zone has dynamic updates enabled,
which _cert-manager_ supports using the RFC2136 plugin.

For now, this is only enabled for _rabbitmq.pyrocufflink.blue_.  I will
transition the other names soon.
2024-12-09 17:58:43 +00:00
Dustin 4243823ba5 invoice-ninja: Fix network policy for ingress
Since the IP address assigned to the ingress controller is now managed
by keepalived and known to Kubernetes, the network policy needs to allow
access to it by pod namespace rather than IP address.  It seems that the
former takes precedence over the latter, so even though the IP address
was explicitly allowed, traffic was not permitted because it was
destined for a Kubernetes service that was not.
2024-12-07 09:28:44 -06:00
Dustin b269fa5812 home-assistant: Add service to shut down desk panel
Home Assistant can now SSH into the desk panel and shut it down.
2024-12-02 23:06:30 +00:00
Dustin 107852ad54 home-assistant: Eable auto-login for desk panel
Home Assistant supports unauthenticated access for certain clients using
its _trusted_network_ auth provider.  With this configuration, we allow
the desk panel to automatically sign in as the _kiosk_ user, but all
other clients must authenticate normally.
2024-11-27 22:03:40 -06:00
Dustin 72d3f222c5 jenkins: Trust SSHCA for pyrocufflink.black
The new machines have names in the _pyrocufflink.black_ zone.  We need
to trust the SSHCA certificate to sign keys for these names in order to
connect to them and manage them with Ansible.
2024-11-26 03:35:21 +00:00
Dustin 2a90ffc7a9 invoice-ninja: Update trusted proxies addresses
Since _ingress-nginx_ no longer runs in the host network namespace,
traffic will appear to come from pods' internal IP addresses now.
Similarly, the network policy for Invoice Ninja needs to be updated to
allow traffic _to_ the ingress controllers' new addresses.
2024-11-22 22:43:16 -06:00
Dustin 1f7631d6b7 home-assistant: Update trusted proxies addresses
Since _ingress-nginx_ no longer runs in the host network namespace,
traffic will appear to come from pods' internal IP addresses now.
2024-11-22 22:42:43 -06:00
Dustin 607fa050f3 firefly-iii: Update trusted proxies addresses
Since _ingress-nginx_ no longer runs in the host network namespace,
traffic will appear to come from pods' internal IP addresses now.
2024-11-22 22:41:49 -06:00
Dustin 0a5af84778 rabbitmq: Configure Service externalIPs
Clients outside the cluster can now communicate with RabbitMQ directly
on port 5671 by using its dedicated external IP address.  This address
is automatically assigned to the node where RabbitMQ is running by
`keepalived`.
2024-11-22 22:39:30 -06:00
Dustin 1a39a8869a h-a/mosquitto: Configure Service externalIPs
Clients outside the cluster can now communicate with Mosquitto directly
on port 8883 by using its dedicated external IP address.  This address
is automatically assigned to the node where Mosquitto is running by
`keepalived`.
2024-11-22 22:37:01 -06:00
Dustin fefbaa9991 ingress: Use Deployment+Service with externalIPs
Now that we have `keepalived` managing the "virtual" IP address for the
ingress controller, we can change _ingress-nginx_ to run as a Deployment
rather than a DaemonSet.  It no longer needs to use the host network
namespace, as `kube-proxy` will route all traffic sent to the configured
external IP address to the controller pods.  Using the _Local_ external
traffic policy disables NAT, so incoming traffic is seen by the
nginx unmodified.
2024-11-22 22:35:37 -06:00
Dustin e7ea2b0659 keepalived: Initial commit
Running `keepalived` as a DaemonSet will allow managing floating
"virtual" IP addresses for Kubernetes services with configured external
IP addresses.  The main services we want to expose outside the cluster
are _ingress-nginx_, Mosquitto, and RabbitMQ.  The `keepalived` cluster
will negotiate using the VRRF protocol to determine which node should
have each external address.  Using the process tracking feature of
`keepalived`, we can steer traffic directly to the node where the target
service is running.
2024-11-22 22:26:48 -06:00
Dustin 5c78bb89b5 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-11-22 19:38:00 -06:00
Dustin 0a6086eb2a longhorn: Run on dedicated nodes
I've created new worker nodes that are dedicated to running Longhorn
replicas.  These nodes are tainted with the
`node-role.kubernetes.io/longhorn` taint, so no regular pods will be
scheduled there by default.  Longhorn pods thus needs to be configured
to tolerate that taint, and to be scheduled on nodes with the
similarly-named label.
2024-11-21 22:59:14 -06:00
Dustin d6c83565ec rabbitmq: Update to 4.0
RabbitMQ Server 3.13 is out of support now.
2024-11-21 22:59:14 -06:00
Dustin 121e6e7111 rabbitmq: Switch to using volume claim templates
This will make it easier to "blow away" the RabbitMQ data volume on the
occasions when it gets into a weird state.  Simply scale the StatefulSet
down to 0 replicas, delete the PVC, then scale back up.  Kubernetes will
handle creating a new PVC automatically.
2024-11-21 22:59:14 -06:00
Dustin 3d5dd52eb9 ingress: Use upstream resources w/ patches
This will make it easier to upgrade, since we keep track of _exactly_
what we changed from the upstream resources with Kustomize patches.
2024-11-21 19:42:35 -06:00
Dustin 3b3d4c38ed dynk8s: Move Wireguard config to SealedSecret 2024-11-21 19:41:55 -06:00
Dustin da81a336e1 dynk8s-provisioner: Migrate to Kustomize 2024-11-19 10:43:42 -06:00
Dustin e0c633c21e v-m: scrape: Fix Nextcloud URL
Nextcloud uses a _client-side_ (Javascript) redirect to navigate the
browser to its `index.php`.  The page it serves with this redirect is
static and will often load successfully, even if there is a problem with
the application.  This causes the Blackbox exporter to record the site
as "up," even when it it definitely is not.  To avoid this, we can
scrape the `index.php` page explicitly, ensuring that the application is
loaded.
2024-11-17 18:43:00 +00:00
Dustin 14492d827a Merge pull request 'home-assistant: Update to 2024.11.2' (#34) from updatebot/home-assistant into master
Reviewed-on: #34
2024-11-16 18:04:43 +00:00
Dustin 444686cb1e Merge pull request 'paperless-ngx: Update to 2.13.0' (#31) from updatebot/paperless-ngx into master
Reviewed-on: #31
2024-11-16 17:55:04 +00:00
Dustin ceea84d7f9 Merge pull request 'firefly-iii: Update to 6.1.22' (#33) from updatebot/firefly-iii into master
Reviewed-on: #33
2024-11-16 17:45:08 +00:00
bot 4d2cc40b5e tika: Update to 3.0.0.0 2024-11-16 12:32:14 +00:00
bot c31db5fde2 gotenberg: Update to 8.13.0 2024-11-16 12:32:14 +00:00
bot 74ce0e1b0a paperless-ngx: Update to 2.13.5 2024-11-16 12:32:14 +00:00
bot f0b16fd53c firefly-iii: Update to 6.1.22 2024-11-16 12:32:12 +00:00
bot acd9a0fa92 zwavejs2mqtt: Update to 9.27.2 2024-11-16 12:32:08 +00:00
bot 115b4ade39 home-assistant: Update to 2024.11.2 2024-11-16 12:32:08 +00:00
Dustin c1927eecfc Merge pull request 'home-assistant: Update to 2024.10.4' (#30) from updatebot/home-assistant into master
Reviewed-on: #30
2024-11-12 15:56:50 +00:00
Dustin 04ef1faf75 Merge pull request 'authelia: Update to 4.38.17' (#32) from updatebot/authelia into master
Reviewed-on: #32
2024-11-12 15:14:50 +00:00
Dustin 0209f921c3 v-m: Remove nut0 from scrape targets
_nut0.pyrocufflink.blue_ is decommissioned.
2024-11-12 08:02:00 -06:00
Dustin 62b19e942b sshca: Add machine ID for nut1.p.b 2024-11-10 11:19:53 -06:00
bot b956e9ac05 authelia: Update to 4.38.17 2024-11-09 12:32:16 +00:00
bot f7eb3b49e7 zwavejs2mqtt: Update to 9.26.0 2024-11-09 12:32:08 +00:00
bot 0db830a670 zigbee2mqtt: Update to 1.41.0 2024-11-09 12:32:08 +00:00
bot 6d137af6dc home-assistant: Update to 2024.11.1 2024-11-09 12:32:08 +00:00
Dustin 3d40424cf7 fleetlock: Use patched server from Github PR
The _fleetlock_ server drains all pods from a node before allocating the
reboot lock to that node.  Unfortunately, it doesn't actually wait for
those pods to be completely evicted.  If some pods take too long to shut
down, they may get stuck in `Terminating` state once the machine starts
rebooting.  This makes it so those pods cannot be replaced on another
node with the original one is offline, which pretty much defeats the
purpose of using Fleetlock in the first place.

It seems upstream has abandoned this project, as there is an open [Pull
Request][0] to fix this issue that has so far been ignored.
Fortunately, building a new container image containing the patch is easy
enough, so we can run our own patched build.

[0]: https://github.com/poseidon/fleetlock/pull/271
2024-11-05 07:05:55 -06:00
Dustin ac62a77c96 Merge branch '20125' 2024-11-05 07:05:19 -06:00
Dustin e1d9833e83 cert-manager: Add cert for apps.du5t1n.xyz 2024-11-05 07:04:27 -06:00
Dustin 4ad5518f18 cert-manager: Migrate config to configMapGenerator 2024-11-05 07:04:09 -06:00
Dustin 9f287d0f71 v-m/alerts: Add alerts for backup RAID array
Just like I did with the RAID-1 array in the old BURP server, I will
keep one member active and one in the fireproof safe, swapping them each
month.  We can use the same metrics queries to alert on when the swap
should happen that we used with the BURP server.
2024-11-04 20:46:03 -06:00
Dustin 2380468658 v-m/scrape: Collect Jellyfin metrics 2024-11-04 20:38:25 -06:00
Dustin db7c07ee55 v-m/scrape: Ignore cloud Kubernetes nodes
The ephemeral Jenkins worker nodes that run in AWS don't have colletcd,
promtail, or Zincati.  We don't needto get three alerts every time a
worker starts up to handle am ARM build job, so we drop these discovered
targets for these scrape jobs.
2024-11-04 20:35:17 -06:00
Dustin d76a1360c8 v-m/alerts: Ignore Paperless consume_file task
Paperless-ngx uses a Celery task to process uploaded files, converting
them to PDF, running OCR, etc.  This task can be marked as "failed" for
various reasons, most of which are more about the document itself than
the health of the application.  The GUI displays the results of failed
tasks when they occur.  It doesn't really make sense to have an alert
about this scenario, especially since there's nothing to do to directly
clear the alert anyway.
2024-11-04 20:28:11 -06:00
Dustin 71b52e4c6f 20125: Deploy Status server
https://20125.home/ is the URL the Status Android application loads in
its main WebView.  This site is powered by a server that generates a
custom page showing the status of our self-hosted applications, based on
alerts retrieved from the AlertManager API.

Android WebView does not allow cleartext HTTP connections.  It does,
however, allow connecting an HTTPS server and ignoring the certificate
it presents, which is effectively the same thing.  Thus, we generate a
self-signed certificate for the Ingress for this site.
2024-11-02 19:51:53 -05:00
Dustin 8ecee4133f v-m/alerts: Rework free disk space alert
Fedora CoreOS fills `/boot` beyond the 75% alert threshold under normal
circumstances on aarch64 machines.  This is not a problem, because it
cleans up old files on its own, so we do not need to alert on it.
Unfortunately, the _DiskUsage_ alert is already quite complex, and
adding in exclusions for these devices would make it even worse.

To simplify the logic, we can use a recording rule to precomupte the
used/free space ratio.  By using `sum(...) without (type)` instead of
`sum(...) on (df, instance)`, we keep the other labels, which we can
then use to identify the metrics coming from machines we don't care to
monitor.

Instead of having different thresholds for different volumes
encoded in the same expression, we can use multiple alerts to alert on
"low" vs "very low" thresholds.  Since this will of course cause
duplicate alerts for most volumes, we can use AlertManager inhibition
rules to disable the "low" alert once the metric crosses the "very low"
threshold.
2024-11-02 09:38:02 -05:00
Dustin 4cef41688f v-m/alerts: Add Zigbee+ZWave network alerts 2024-11-01 18:14:56 -05:00
Dustin 6cf11f9f61 v-m: Scrape HAProxy 2024-11-01 18:14:37 -05:00
Dustin 7a768cbb76 v-m: Update jobs for new Loki server
*loki1.pyrocufflink.blue* is a regular Fedora machine, a member of the
AD domain, and managed by Ansible.  Thus, it does not need to be
explicitly listed as a scrape target.

For scraping metrics from Loki itself, I've changed the job to use
DNS-SD because it seems like `vmagent` does _not_ re-resolve host names
from static configuration.
2024-11-01 18:07:34 -05:00
Dustin 0101040634 v-m/alerts: Add Paperless-ngx email task alert
This alert should fire if the background task to fetch e-mail and import
them into Paperless-ngx has not run for a while.
2024-11-01 18:04:06 -05:00
Dustin 3f9601dc94 v-m/alerts: Improve Paperless-ngx Celery task alert
The `flower_events_total` metric is a counter, so its value only ever
increases (discounting restarts of the server process).  As such,
nonzero values do not necessarily indicate a _current_ problem, but
rather that there was one at some point in the past.  To identify
current issues, we need to use the `increase` function, and then apply
the `max_over_time` function so that the alert doesn't immediately reset
itself.
2024-11-01 18:00:50 -05:00
Dustin d12e66f58a v-m: Scrape Frigate exporter 2024-11-01 17:47:51 -05:00
Dustin 045eea89a9 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-10-19 09:49:59 -05:00
Dustin 8ff45a8c01 paperless-ngx/gotenberg: Run as correct user
The Gotenberg container image uses UID 1001 for the _gotenberg_ user.
Using any other UID number, even when the home directory is set and
owned by that UID, results in random issues, especially when using
LibreOffice conversions.
2024-10-19 09:46:15 -05:00
giteadmin d3e00680c0 Merge pull request 'home-assistant: Update to 2024.10.3' (#29) from updatebot/home-assistant into master
Reviewed-on: #29
2024-10-19 13:13:12 +00:00
bot c5daf23f71 mosquitto: Update to 2.0.20 2024-10-19 11:32:16 +00:00
bot 6e2c8d1a25 zwavejs2mqtt: Update to 9.24.0 2024-10-19 11:32:16 +00:00
bot 0e3f719e32 whisper: Update to 2.2.0 2024-10-19 11:32:16 +00:00
bot 94e10207d2 home-assistant: Update to 2024.10.3 2024-10-19 11:32:15 +00:00
Dustin 99c8f7694c paperless-ngx: Split resources into separate files
The Paperless-ngx ecosystem consists of several services.  Defining the
resources for each service in separate manifest files will make
maintenance a little bit easier.
2024-10-17 07:27:33 -05:00
Dustin e19e8f50ab v-m/alerts: Add alerts for Paperless-ngx 2024-10-17 07:18:23 -05:00
Dustin 78651eb5f8 v-m/alerts: Add alerts for PostgreSQL WAL archiver 2024-10-17 07:18:09 -05:00
Dustin ee3e078b20 v-m/alerts: Add alerts for Restic backups 2024-10-17 06:58:48 -05:00
Dustin ea89e0cde4 v-m/scrape: Remove synapse job
The Synapse server is now completely decommissioned.
2024-10-17 06:50:27 -05:00
Dustin e581957f9d Merge remote-tracking branch 'refs/remotes/origin/master' 2024-10-15 07:59:42 -05:00
Dustin b01300f8cc Merge pull request 'zwavejs2mqtt: Update to 9.20.0' (#26) from updatebot/home-assistant into master
Reviewed-on: #26
2024-10-15 12:43:28 +00:00
bot 55ae979a1d mosquitto: Update to 2.0.19 2024-10-15 12:42:36 +00:00
bot 1de05f2ccc zwavejs2mqtt: Update to 9.23.0 2024-10-15 12:42:36 +00:00
bot 58f7f9e2cc zigbee2mqtt: Update to 1.40.2 2024-10-15 12:42:35 +00:00
bot 390eacf209 home-assistant: Update to 2024.10.2 2024-10-15 12:42:35 +00:00
Dustin 145fa6286e storage: Add Longhorn backup target secret
Longhorn uses a special Secret resource to configure the backup target.
This secret includes the credentials and CA certificate for accessing
the MinIO S3 service.

Longhorn must be configured to use this Secret by setting the
`backup-target-credential-secret` setting to
`minio-backups-credentials`.
2024-10-13 14:03:49 -05:00
Dustin 1b4bb234c8 Merge pull request 'gotenberg: Update to 8.10.0' (#25) from updatebot/paperless-ngx into master
Reviewed-on: #25
2024-10-12 20:44:58 +00:00
Dustin 7e2512c261 Merge pull request 'authelia: Update to 4.38.12' (#28) from updatebot/authelia into master
Reviewed-on: #28
2024-10-12 20:44:41 +00:00
bot 281ec623c4 authelia: Update to 4.38.16 2024-10-12 11:33:03 +00:00
bot 51fe6f39af gotenberg: Update to 8.12.0 2024-10-12 11:33:00 +00:00
Dustin 2ccbcd494c firefly-iii: Update to 6.1.21
Notably, this version fixes the ~4s delay when creating/editing
transactions.
2024-10-02 09:08:58 -05:00
Dustin e9bfc63a74 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-10-02 09:08:31 -05:00
Dustin 32171cc76e Merge pull request 'firefly-iii: Update to 6.1.20' (#27) from updatebot/firefly-iii into master
Reviewed-on: #27
2024-09-29 21:09:41 +00:00
bot 71f091fa05 firefly-iii: Update to 6.1.20 2024-09-28 11:32:18 +00:00
Dustin df50decba1 argocd: apps/authelia: Enable auto-sync
This way, merging PRs from *updatebot* will automatically trigger
updating Paperless-ngx et al.
2024-09-24 07:16:45 -05:00
Dustin 0022171616 argocd: apps/ntfy: Enable auto-sync
This way, merging PRs from *updatebot* will automatically trigger
updating Paperless-ngx et al.
2024-09-24 07:16:34 -05:00
Dustin a149bc8761 updatebot: Manage Authelia 2024-09-24 07:15:41 -05:00
Dustin 76588c3e20 updatebot: Manage Mosquitto 2024-09-24 07:08:56 -05:00
Dustin bdc24e1778 updatebot: Manage ntfy 2024-09-24 07:05:37 -05:00
Dustin 982cd88255 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-09-22 12:13:58 -05:00
Dustin ffa47b9fba v-m: Scrape ntfy
_ntfy_ has supported Prometheus metrics for a while now, so let's
collect them.
2024-09-22 12:13:01 -05:00
Dustin 9ec6b651c1 v-m: Scrape wal-g via statsd_exporter
The database server now runs _statsd_exporter_, which receives metrics
from WAL-G whenever it saves WAL segments or creates backups.
2024-09-22 12:11:59 -05:00
Dustin c83ceee994 v-m: Quit scraping Jenkins with blackbox_exporter
I was doing this to monitor Jenkins's certificate, but since that's
managed by _cert-manager_, there's really practically no risk of it
expiring without warning anymore.  Since Jenkins is already being
scraped directly, having this extra check just gernerates extra
notifications when there is an issue without adding any real value.
2024-09-22 12:10:03 -05:00
Dustin 3f39747557 v-m: Redo Internet/DNS connectivity checks (again)
Using domain names in the "blackbox" probe makes it difficult to tell
the difference between a complete Internet outage and DNS issues.  I
switched to using these names when I changed how the firewall routed
traffic to the public DNS servers, since those were the IP addresses
I was using to determine if the Internet was "up."  I think it makes
sense, though, to just ping the upstream gateway for that check.  If
EverFast changes their routing or numbering, we'll just have to update
our checks to match.
2024-09-22 12:06:03 -05:00
Dustin 8f354a4460 v-m/alertmanager: Suppress battery low alerts
The alerts for Z-Wave device batteries in particular are pretty
annoying, as they tend to "flap" for some reason.  I like having the
alerts show up on Alertmanager/Grafana dashboards, but I don't
necessarily need notifications about them.  Fortunately, we can create a
special "none" receiver and route notifications there, which does
exactly what we want here.
2024-09-22 12:01:02 -05:00
Dustin 1c6286a977 ntfy: Migrate to Kustomize
Using Kustomize, we can define the configuration file separately from
the Kubernetes resources, and use `configMapGenerators` to generate the
ConfigMap for it.  Additionally, this will make it possible to update
_ntfy_ using `updatebot`.
2024-09-22 12:00:28 -05:00
Dustin a6683c9123 invoice-ninja: Move under pyrocufflink.net
Tabitha wants to be able to accept Apple Pay payemnts via stripe, but
this requires an additional "domain verification" step.  Apple needs to
make an HTTP request to the domain owned by the vendor, which in the
case of Invoice Ninja, must be the "app URL."  Unfortunately, there
does not appear to be a way to tell Apple/Stripe/IN to use the client
portal domain or any other domain besides the app URL.  Therefore, we
need to expose Invoice Ninja to the Internet under the public
_pyrocufflink.net_ domain, rather than the internal _pyrocufflink.blue_.
2024-09-22 11:55:10 -05:00
Dustin f5b79cfdf8 updatebot: Schedule updats on Saturday morning
Let's run `updatebot` on Saturday morning, so I can apply the changes
over the weekend if I have time.  If I don't, there's no harm in having
the PRs open for a few days until I can get to it during the week.
2024-09-22 11:53:52 -05:00
Dustin 4cab489534 Merge pull request 'home-assistant: Update to 2024.9.2' (#24) from updatebot/home-assistant into master
Reviewed-on: #24
2024-09-22 15:48:47 +00:00
bot ceaa9cd2cb zwavejs2mqtt: Update to 9.19.0 2024-09-22 15:44:40 +00:00
bot 669029ea33 home-assistant: Update to 2024.9.2 2024-09-22 15:44:39 +00:00
Dustin f07122897b Merge pull request 'paperless-ngx: Update to 2.12.1' (#23) from updatebot/paperless-ngx into master
Reviewed-on: #23
2024-09-16 19:30:31 +00:00
bot f451f03c68 paperless-ngx: Update to 2.12.1 2024-09-16 11:32:12 +00:00
Dustin 05c325656e Merge pull request 'paperless-ngx: Update to 2.12.0' (#22) from updatebot/paperless-ngx into master
Reviewed-on: #22
2024-09-09 13:47:52 +00:00
bot 70589b7e51 paperless-ngx: Update to 2.12.0 2024-09-09 11:32:10 +00:00
Dustin 551f945364 authelia: Add callback URL for MinIO on Chromie 2024-09-08 20:27:02 -05:00
Dustin 26422d9f3c restic-exporter: Point at chromie.p.b
Restic backups are now stored in MinIO on _chromie.pyrocufflink.blue_.
All data have been migrated from _burp1.p.b_, which is being
decommissioned.

The instance of MinIO on _chromie_ uses a certificate signed by DCH CA,
rather than the _pyrocufflink.blue_ wildcard certificate signed by
ZeroSSL.  As such, we need to configure `restic` to trust the DCH Root
CA certificate in order to use the MinIO S3 API.
2024-09-08 20:24:43 -05:00
Dustin 05e40c8ad3 Merge pull request 'home-assistant: Update to 2024.9.1' (#20) from updatebot/home-assistant into master
Reviewed-on: #20
2024-09-09 01:07:14 +00:00
Dustin 3ae5f9e5ca Merge pull request 'paperless-ngx: Update to 2.11.6' (#21) from updatebot/paperless-ngx into master
Reviewed-on: #21
2024-09-09 01:02:19 +00:00
Dustin f17ad4f779 updatebot: Updates for latest version
The latest version of `updatebot` has two major changes:

1. Projects can encompass multiple images, eliminating the need for
   multiple configuration files and CronJobs.  Projects are now defined
   in a YAML documen, since the data structure is very nested and is
   cumbersome to express in TOML.
2. Pull requests can now include a diff of the resources that will
   change if the PR is merged.  This requires the `kubectl` and `diff`
   programs (which are not currently included in the _updatebot_
   container image, so we bind-mount them from the host) and permission
   to compare the local manifests using the Kubernetes API.  Oddly,
   computing the diff requires permission to use the PATCH method, even
   though the client is not requesting any changes.  This is apparently
   a long-standing bug ([issue #981][0]) that may or may not ever be
   fixed.

[0]: https://github.com/kubernetes/kubectl/issues/981
2024-09-08 19:54:58 -05:00
Dustin 4d643bdc9a paperless-ngx: Update image ref for Tika
The Paperless-ngx project no longer maintains their own builds of Apache
Tika container images.
2024-09-08 19:51:47 -05:00
bot 8b7ae74e41 tika: Update to 2.9.2.1 2024-09-09 00:50:55 +00:00
bot 5f9ab83a57 gotenberg: Update to 8.9.2 2024-09-09 00:50:54 +00:00
bot 9c2e44ff63 paperless-ngx: Update to 2.11.6 2024-09-09 00:50:54 +00:00
bot 128a434b09 zwavejs2mqtt: Update to 9.18.1 2024-09-09 00:50:50 +00:00
bot db93ebf336 zigbee2mqtt: Update to 1.40.1 2024-09-09 00:50:50 +00:00
bot b825b8a272 home-assistant: Update to 2024.9.1 2024-09-09 00:50:50 +00:00
Dustin 431395f18f Merge remote-tracking branch 'refs/remotes/origin/master' 2024-09-08 10:32:30 -05:00
Dustin f182479d34 v-m: Remove BURP metrics, alerts
BURP is officially decommissioned, replaced by Restic.
2024-09-05 20:16:01 -05:00
Dustin f3e20077b2 Merge pull request 'zigbee2mqtt: Update to 1.40.0' (#13) from updatebot/home-assistant into master
Reviewed-on: #13
2024-09-03 14:40:02 +00:00
bot 10c813b973 zwavejs2mqtt: Update to 9.18.0 2024-09-02 11:32:06 +00:00
bot 760829e221 zigbee2mqtt: Update to 1.40.0 2024-09-02 11:32:06 +00:00
Dustin 4adb9cd243 sshca: Add machine IDs for VM hosts 2024-08-31 17:49:36 -05:00
Dustin 9fb0510625 Merge pull request 'firefly-iii: Update to 6.1.19' (#11) from updatebot/firefly-iii into master
Reviewed-on: #11
2024-08-28 22:41:46 +00:00
Dustin 4436ec5c6c sshca: Add machine ID for chromie.p.b
*chromie.pyrocufflink.blue* runs on the same hardware that was
originally *nvr1.pyrocufflink.blue*.
2024-08-28 11:57:49 -05:00
Dustin 2589f475d9 argocd: apps: Remove PostgreSQL 2024-08-27 19:09:52 -05:00
Dustin b291d9f570 argocd: apps/paperless-ngx: Enable auto-sync
This way, merging PRs from *updatebot* will automatically trigger
updating Paperless-ngx et al.
2024-08-27 19:06:13 -05:00
Dustin 25b8b3001f argocd: apps/firefly-iii: Enable auto-sync
This way, merging PRs from *updatebot* will automatically trigger
updating Firefly-III.
2024-08-27 19:05:34 -05:00
Dustin 7117ef455b updatebot: Add CronJob for Paperless-ngx
Paperless-ngx updates also need to cover Gotenberg and Apache Tika.
2024-08-27 18:59:00 -05:00
Dustin 7c1fed7685 updatebot: Schedule updatebot for Firefly-III
Firefly-III only has a single Pod/container to manage with `updatebot`.
2024-08-27 18:19:34 -05:00
Dustin 5de1379c1f updatebot: Add CronJob to run for Home Assistant
`updatebot` is a script I wrote that automatically opens Gitea Pull
Requests to update container image references in Kubernetes resource
manifests.  It checks Github or Docker Hub for the latest release and
updates manifests or Kustommization configuration files to point to the
current version.  It then commits the changes and opens a pull request
in Gitea.  When combined with ArgoCD automatic synchronization, this
makes updating Kubernetes-deployed applications as simple as clicking
the merge button in the Gitea PR.

To start with, we'll automate Home Assistant upgrades this way.
2024-08-27 18:05:50 -05:00
bot b323984d6c firefly-iii: Update to 6.1.19 2024-08-27 20:22:01 +00:00
Dustin ab107022f4 home-assistant: Remove Tonight's Forecast sensor
This template sensor will be migrated to a helper, since Home Assitant
removed the `forecast` attribute of weather sensors and now requires
calling an action (service) to get those data.
2024-08-27 09:46:56 -05:00
Dustin b60ed65c80 home-assistant: whisper: Add tmp volume
`faster-whisper` now requires writable temporary storage.
2024-08-27 09:35:57 -05:00
Dustin 7fb0932084 home-assistant: Remove unused template sensors 2024-08-27 09:34:08 -05:00
Dustin 01e95d22db home-assistant: Remove Matrix integration
The _hatch.chat_ Matrix homeserver is being retired.  We don't use
Matrix for any notifications any more.
2024-08-27 09:27:37 -05:00
Dustin bcfd94948d home-assistant: Remove deprecated YAML config
These configuration settings are no longer supported in the YAML
document, but configured via the UI.
2024-08-27 09:12:34 -05:00
Dustin fd7b90bb1c Merge pull request 'home-assistant: Update to 2024.8.3' (#10) from updatebot/home-assistant into master
Reviewed-on: #10
2024-08-27 13:58:02 +00:00
Dustin 1267032847 argocd: apps/home-assistant: Enable auto-sync
This way, merging PRs from *updatebot* will automatically trigger
updating Home Assistant et al.
2024-08-27 08:57:03 -05:00
bot ca80663c29 zwavejs2mqtt: Update to 9.17.0 2024-08-26 15:22:17 +00:00
bot d16cca534a zigbee2mqtt: Update to 1.39.1 2024-08-26 15:22:17 +00:00
bot d78f17f529 piper: Update to 1.5.0 2024-08-26 15:22:17 +00:00
bot 5a33f55d38 whisper: Update to 2.1.0 2024-08-26 15:22:16 +00:00
bot 39c576a6eb home-assistant: Update to 2024.8.3 2024-08-26 15:22:16 +00:00
Dustin 9c50acb6b9 ntfy: Handle ntfy.pyrocufflink.net name
Now that the reverse proxy that handles requests from the Internet uses
TLS pass-through, the Ingress for _ntfy_ needs to recognize both the
internal and external name.
2024-08-24 11:31:47 -05:00
Dustin a443929c0c websites: Manage dcow cert via Ingress annotation
Now that the reverse proxy for Internet-facing sites uses TLS
passthrough, the certificate for the _darkchestofwonders.us_ Ingress
needs to be correct.  Since Ingress resources can only use either the
default certificate (_*.pyrocufflink.blue_) or a certificate from their
same namespace, we have to move the Certificate and its corresponding
Secret into the _websites_ namespace.  Fortunately, this is easy enoug
to do, by setting the appropriate annotations on the Ingress.

To keep the existing certificate (until it expires), I moved the Secret
manually:

```sh
kubectl get secret dcow-cert -o yaml | grep -v namespace | kubectl create -n websites -f -
```
2024-08-24 11:30:56 -05:00
Dustin 78afee9abc v-m/scrape: Remove static VM hosts from collectd
The VM hosts are now managed by the "main" Ansible inventory and thus
appear in the host list ConfigMap.  As such, they do not need to be
listed explicitly in the static targets list.
2024-08-23 09:28:05 -05:00
Dustin 94b7168b1e home-assistant: Add restart MQTTMarionette script
There's obviously a bug or something in `mqttmarionette` because it
occasionally gets "stuck" in a state where it is running but does
not reconnect to the MQTT broker.  In such situations, it has to be
restarted (and even then it doesn't shut down correctly but has to
be killed with SIGKILL, usually).  I have been doing this manually, but
with this shell script and a corresponding "shell command" integration
in Home Assistant, it can be done automatically.  This is similar to
how Home Assistant restarts Mopidy on the living room stereo when it
gets into the same kind of state.
2024-08-23 09:24:46 -05:00
Dustin 7dffb5195a v-m: alertmanager: Group disk usage alerts
Some machines have the same volume mounted multiple times (e.g.
container hosts, BURP).  Alerts will fire for all of these
simultaneously when the filesystem usage passes the threshold.  To avoid
getting spammed with a bunch of messages about the same filesystem,
we'll group alerts from the same machine.
2024-08-17 10:59:05 -05:00
Dustin 02001f61db v-m/scrape: webistes: Stop scraping Matrix
I'm not using Matrix for anything anymore, and it seems to have gone
offline.  I haven't fully decommissioned it yet, but the Blackbox scrape
is failing, so I'll just disable that bit for now.
2024-08-17 10:57:22 -05:00
Dustin c7e4baa466 v-m: scrape: Remove nvr2.p.b Zincati scrape target
I've redeployed *nvr2.pyrocufflink.blue* as Fedora Linux, so it does not
run Zincati anymore.
2024-08-17 10:56:06 -05:00
Dustin 1a631bf366 v-m: scrape: Remove serial1.p.b
This machine never worked correctly; the USB-RS232 adapters would stop
working randomly (and of course it would be whenever I needed to
actually use them).  I thought it was something wrong with the server
itself (a Raspberry Pi 3), but the same thing happened when I tried
using a Pi 4.

The new backup server has a plethora of on-board RS-232 ports, so I'm
going to use it as the serial console server, too.
2024-08-17 10:54:21 -05:00
Dustin 6f7f09de85 v-m: scrape: Update Unifi server target
I've rebuilt the Unifi Network controller machine (again);
*unifi3.pyrocufflink.blue* has replaced *unifi2.p.b*.  The
`unifi_exporter` no longer works with the latest version of Unifi
Network, so it's not deployed on the new machine.
2024-08-17 10:52:51 -05:00
Dustin 809676f691 v-m: alerts: Add Longhorn alerts 2024-08-17 10:51:13 -05:00
Dustin 9977bb3de4 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-08-06 08:03:42 -05:00
Dustin dcd3f898c7 xactmon: Deploy Invoice Ninja importer for HLC
Bank notifications sent to Tabitha's mailbox are now processed by
`xactmon` and imported into Invoice Ninja as expenses for Hatch Learning
Center.
2024-08-03 13:39:17 -05:00
Dustin 5b34547730 h-a: Config Zigbee2MQTT w/ env vars
Zigbee2MQTT commits the cardinal sin of storing state in its
configuration file.  This means the file has to be writable and thus
stored in persistent storage rather than in a ConfigMap.  As a
consequence, making changes to the configuration when the application is
not running is rather difficult.  Case in point: when I added the
internal alias for _mqtt.pyrocufflink.blue_ pointing to the in-cluster
service, Zigbee2MQTT became unable to connect to the broker because it
was using the node port instead of the internal port.  Since it could
not connect to the broker, it refused to start, and thus the container
would not stay running long enough to fix the configuration to point
to the correct port.

Fortunately, Zigbee2MQTT also allows configuring settings via
environment variables, which can be managed with a ConfigMap.  Luckily,
the values read from environment variables override those from the
configuration file, so pointing to the correct broker port with the
environment variable was sufficient to allow the application to start.
2024-08-01 09:27:52 -05:00
Dustin b366532c88 cert-manager, step-ca: Bypass cluster DNS
Having name overrides for in-cluster services breaks ACME challenges,
because the server tries to connect to the Service instead of the
Ingress.  To fix this, we need to configure both _cert-manager_ and
_step-ca_ to *only* resolve names using the network-wide DNS server.
2024-07-29 20:58:18 -05:00
Dustin a785fcec73 sshca: Allow Jenkins jobs to restart the Deployment
The Jenkins job for the SSHCA Server restarts the Deployment after
building a new container image.
2024-07-27 13:10:20 -05:00
Dustin a26857819a step-ca: Add Ingress resource
It turns out, `step ca renew` _can_ renew certificates without mTLS; it
has a `--mtls=false` command-line argument that configures it to use
a JWT signed by the certificate, instead of using the certificate at
the transport layer.  This allows clients to renew their certificates
without needing another authentication mechanism, even with the
TLS-terminating proxy.
2024-07-27 13:07:26 -05:00
Dustin 079c3871b9 invoice-ninja: Fix document upload feature
Invoice Ninja allows attaching documents to invoices, payments,
expenses, etc.  Tabitha wants to use this feature to attach receipts for
her expenses, but the photos her phone takes of them are too large for
the default nginx client body limit.  We can raise this limit on the
ingress, but we also need to raise it on the "inner" nginx.
2024-07-27 13:04:02 -05:00
Dustin e74a6b3142 invoice-ninja: Run in a mutable container
The Invoice Ninja container is not designed to be immutable at all; it
makes a bunch of changes to its own contents when it starts up.
Notably, it copies the contents of the `public` and `storage`
directories from the container image to the persistent volume _and then
deletes the source_.  Additionally, being a Laravel application, it
needs write access to its own code for caching, etc.  Previously, the
`init.sh` script copied the entire `app` directory to a temporary
directory, and then the runtime container mounted that volume over the
top of the original location.  This allowed the root filesystem of the
container to be read-only, while the `app` directory was still mutable.
Unfortunately, this makes the startup process incredibly slow, as it
takes a couple of minutes to copy the whole application.  It's also
pretty pointless, because the application runs as an unprivileged
process, so it wouldn't have write access to the rest of the filesystem
anyway.  As such, I've decided to remove the `readOnlyRootFilesytem`
restriction, and allow the container to run as upstream intends, albeit
begrudgingly.
2024-07-27 12:57:02 -05:00
Dustin 78cd26c827 v-m: Scrape metrics from RabbitMQ 2024-07-26 20:59:00 -05:00
Dustin e56a38c034 cert-manager: Add dch-ca issuer
In-cluster services can now get certificates signed by the DCH CA via
`step-ca`.  This issuer uses ACME with the HTTP-01 challenge, so it
can only issue certificates for names in the _pyrocufflink.blue_ zone
that point to the ingress controllers.
2024-07-26 20:59:00 -05:00
Dustin 54187176ba ingress: Proxy AMQP
Passing port 5671 through the ingress-nginx proxy to the `rabbitmq`
service will allow clients outside the cluster to connect to it.

While we're at it, we'll move the definition of the `tcp-services`
ConfigMap to its own file to make it easier to maintain.
2024-07-26 20:59:00 -05:00
Dustin 1a1d8ff27d rabbitmq: Deploy RabbitMQ Server
RabbitMQ is an AMQP message broker.  It will be used by `xactmon` to
pass messages between the components.

Although RabbitMQ can be deployed in a high-availability cluster, we
don't really need that level of robustness for `xactmon`, so we will
just run a single instance.  Deploying a single-host RabbitMQ server
is pretty straightforward.

We're using mTLS authentication; clients need to have a certificate
issued by the *RabbitMQ CA* in order to connect to the message broker.
The `rabbitmq-ca` _cert-manager_ ClusterIssuer issues these certificates
for in-cluster services like `xactmon`.
2024-07-26 20:59:00 -05:00
Dustin a04a2b5334 xactmon: Deploy xactmon
`xactmon` is a new tool I developed to parse transaction notifications
from banks and automatically import them into my personal finance
tracker.  It is designed in a modular fashion, composed of three main
components:

* Receiver
* Processor
* Importer

Components communicate with one another using an AMQP exchange.
Hypothetically, there could be multipel implementations of the receiver
and importer components.  Right now, there is only a JMAP receiver,
which fetches email messages (from Fastmail), and a Firefly III
importer.  The processor is a singleton, handling notifications from the
receiver, parsing them into a normalized format, and passing them on to
the importer.  It uses a set of rules to decide how to parse the
messages, and supports using either a regular expression with named
capture groups or an Awk script to extract the relevant information.
2024-07-26 20:53:19 -05:00
Dustin ccc46288c2 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-07-22 08:12:11 -05:00
Dustin f4d41c0ec7 invoice-ninja: Add Ingress for HLC client portal
Tabitha wants to use the Invoice Ninja Client Portal and Stripe
integration for customer payments.
2024-07-14 15:41:14 -05:00
Dustin 989556d458 cert-manager: Update to v1.14.5 2024-07-14 15:14:44 -05:00
Dustin 74fa9264df xactfetch: Configure secretsocket
The `xactfetch` script now uses a helper tool, `secretsocket` to
handle looking up secrets.  This tool supports various secret source
types, including files, environment variables, and external commands.
Separating this functionality out of the main script makes it a lot
more flexible and pluggable.  It's main purpose, though, was actually
to allow `xactfetch` to run in a container while communicating with
`rbw` outside that container, specifically for development puposes.

The `secretsocket` tool reads its configuration from a TOML document.
This document defines the secrets the tool handles, and how to look
them up.

Note that the `xactfetch` container image no longer defines the
`XDG_CONFIG_HOME` environment variable, as it uses Chromium instead of
Firefox now, and the former does not work with a read-only config
directory.  As such, we have to mount the `rbw` configuration in the
default location.
2024-07-11 22:49:07 -05:00
Dustin 71ca910ef7 home-assistant: Add Tabitha's HLC calendar 2024-07-11 22:15:56 -05:00
Dustin ee00412bf6 xactfetch: Use separate CronJobs per bank
Usually, `xactfetch` will only fail for one bank or the other.  Rarely
do we want to redownload the data from both banks just because one
failed.  The latest version of `xactfetch` supports specifying a bank
name as a CLI argument, so now we can define separate jobs for each
bank.  Then, when one Job fails, only that one will be retried later.

It's kind of a bummer that it's so repetitive to define two CronJobs
that differ by only a single command-line argument.  I suppose that's
a good argument for using one of the preprocessor tools like Jsonnet
or KCL.
2024-07-11 22:09:27 -05:00
Dustin c741d04d54 xactfetch: Skip wait for manual runs
When the `xactfetch` CronJob is triggered manually, it will now skip
the `sleep` step.  Presumably, whoever triggered it wants the script
to run _right now_, probably to diagnose a problem.
2024-07-11 22:07:54 -05:00
Dustin 8cb292a4b2 v-m: alerts: Add alert for temperatures
After the incident this week with the CPU overheating on _vmhost1_, I
want to make sure I know as soon as possible when anything is starting
to get too hot.
2024-07-11 22:07:27 -05:00
Dustin 8113e5a47f v-m: Fix syntax in AlertManager config
The `group_by` field takes a list of label names, rather than a single
string.
2024-07-06 07:13:27 -05:00
Dustin 952ab9f264 v-m: alertmanager: Group camera notifications
When Frigate is down, multiple alerts are generated for each camera, as
Home Assistant creates camera entities for each tracked object.  This is
extremely annoying, not to mention unnecessary.  To address this, we'll
configure AlertManager to send a single notification for alerts in the
group.
2024-07-05 07:30:30 -05:00
Dustin 9b26753e73 v-m: alerts: Add durations to spammy alerts
Let's avoid sending alerts immediately when something is unavailable,
because the issue might be transient and will resolve itself shortly.
2024-07-05 07:23:38 -05:00
Dustin fa80b15a71 jenkins: Remove Argo CD sync hook
Since Jenkins no longer uses a Longhorn volume, this sync hook is not
useful.
2024-07-04 06:53:58 -05:00
Dustin 248a9a5ae9 v-m: Scrape PostgreSQL exporter
The [postgres exporter][0] exposes metrics about the operation and
performance of a PostgreSQL server.  It's currently deployed on
_db0.pyrocufflink.blue_, the primary server of the main PostgreSQL
cluster.

[0]: https://github.com/prometheus-community/postgres_exporter
2024-07-02 18:16:05 -05:00
Dustin 215b2c6975 home-assistant: Use external PostgreSQL server
Home Assistant uses PostgreSQL for recording the history of entity
states.  Since we had been using the in-cluster database server for
this, the data were migrated to the new external PostgreSQL server
automatically when the backup from the former was restored on the
latter.  It follows, then, that we can point Home Assistant to the
new server as well.

Home Assistant uses SQLAlchemy, which in turn uses _libpq_ via
_psycopg_, as a client for PostgreSQL.  It doesn't expose any
configuration parameters beyond the "database URL" directly, but we
can use the standard environment variables to specify the certificate
and private key for authentication.  In fact, the empty `postgresql://`
URL is sufficient, and indicates that _all_ of the connection parameters
should be taken from environment variables.  This makes specifying the
parameters for both the `wait-for-db` init container and the main
container take the exact same environment variables, so we can use
YAML anchors to share their definitions.
2024-07-02 18:16:05 -05:00
Dustin a269f8a1ae firefly-iii: Connect to external PostgreSQL
Since the new database server outside the Kubernetes cluster, created
for Authelia, was seeded from a backup of the in-cluster server, it
already contained the data from Firefly-III as well.  Thus, we can
switch Firefly-III to using it, too.

The documentation for Firefly-III does not mention anything about how
to configure it to use certificate-based authentication for PostgreSQL,
as is required by the new server.  Fortunately, it ultimately uses
_libpq_, so the standard `PG...` environment variables work fine.  We
just need a certificate issued by the _postgresql-ca_ ClusterIssuer and
the _DCH Root CA_ certificate mounted in the Firefly-III container.
2024-07-02 18:16:05 -05:00
Dustin 92497004be authelia: Point to external PostgreSQL server
If there is an issue with the in-cluster database server, accessing the
Kubernetes API becomes impossible by normal means.  This is because the
Kubernetes API uses Authelia for authentication and authorization, and
Authelia relies on the in-cluster database server.  To solve this
chicken-and-egg scenario, I've set up a dedicated PostgreSQL database
server on a virtual machine, totally external to the Kubernetes cluster.

With this commit, I have changed the Authelia configuration to point at
this new database server.  The contents of the new database server were
restored from a backup from the in-cluster server, so of Authelia's
state was migrated automatically.  Thus, updating the configuration is
all that is necessary to switch to using it.

The new server uses certificate-based authentication.  In order for
Authelia to access it, it needs a certificate issued by the
_postgresql-ca_ ClusterIssuer, managed by _cert-manager_.  Although the
environment variables for pointing to the certificate and private key
are not listed explicitly in the Authelia documentation, their names
can be inferred from the configuration document schema and work as
expected.
2024-07-02 18:16:05 -05:00
Dustin a8ef4c7a80 v-m: Add component labels to configmaps
Adding a `component` label to each ConfigMap will make it possible to
target them specifically, e.g. with `kubectl apply -l`.
2024-07-02 18:16:05 -05:00
Dustin 65e53ad16d v-m: Scrape Zinciti metrics from K8s nodes
All the Kubernetes nodes (except *k8s-ctrl0*) are now running Fedora
CoreOS.  We can therefore use the Kubernetes API to discover scrape
targets for the Zincati job.
2024-07-02 18:16:05 -05:00
Dustin 31345bee7b home-assistant: Add Pool Time WebDAV calendar
I've created a _Pool Time_ calendar in Nextcloud that we can use to
mark when people are expected to be in the pool.  Using this, we can
configure the "someone is in the pool" alert not to fire during times
when we know people will be in the pool.  This will make it much less
annoying on HLC pool days.
2024-07-02 18:16:05 -05:00
Dustin 2d7fec1cdf v-m: vmstorage: Add pod anti-affinity
One of the reasons for moving to 4 `vmstorage` replicas was to ensure
that the load was spread evenly between the physical VM host machines.
To ensure that is the case as much as possible, we need to keep one
pod per Kubernetes node.
2024-06-26 18:29:49 -05:00
Dustin f7f408ca8c v-m: Redo vmstorage persistent volumes
Longhorn does not work well for very large volumes.  It takes ages to
synchronize/rebuild them when migrating between nodes, which happens
all too frequently.  This consumes a lot of resources, which impacts
the operation of the rest of the cluster, and can cause a cascading
failure in some circumstances.

Now that the cluster is set up to be able to mount storage directly from
the Synology, it makes sense to move the Victoria Metrics data there as
well.  Similar to how I did this with Jenkins, I created
PersistentVolume resources that map to iSCSI volumes, and patched the
PersistentVolumeClaims (or rather the template for them defined by the
StatefulSet) to use these.  Each `vmstorage` pod then gets an iSCSI
LUN, bypassing both Longhorn and QEMU to write directly to the NAS.

The migration process was relatively straightforwrad.  I started by
scaling down the `vminsert` Deployment so the `vmagent` pods would
queue the metrics they had collected while the storage layer was down.
Next, I created a [native][0] export of all the time series in the
database.  Then, I deleted the `vmstorage` StatefulSet and its
associated PVCs.  Finally, I applied the updated configuration,
including the new PVs and patched PVCs, and brought the `vminsert`
pods back online.  Once everything was up and running, I re-imported
the exported data.

[0]: https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-export-data-in-native-format
2024-06-26 18:29:49 -05:00
Dustin 0f24341e5c collectd: Add DaemonSet for collectd
Since all the nodes in the cluster run Fedora CoreOS now, we can
deploy collectd as a container, managed by a DaemonSet.

Note that while _collectd_ has to run as _root_ in order to collect
a lot of metrics, it should not run with all privileges.  It does need
to run as a "super-privileged container" (`spc_t` SELinux domain), but
it does _not_ need most kernel capabilities.
2024-06-26 18:29:49 -05:00
Dustin ab458df415 v-m/vmstorage: Start pods in parallel
By default, Kubernetes waits for each pod in a StatefulSet to become
"ready" before starting the next one.  If there is a problem starting
that pod, e.g. data corruption, then the others will never start.  This
sort of defeats the purpose of having multiple replicas.  Fortunately,
we can configure the pod management policy to start all the pods at
once, regardless of the status of any individual pod.  This way, if
there is a problem with the first pod, the others will still come up
and serve whatever data they have.
2024-06-26 18:29:49 -05:00
Dustin 14be633843 v-m: Scrape Restic exporter 2024-06-26 18:29:49 -05:00
Dustin 5079599423 restic-exporter: Deploy Restic Prometheus exporter
The [restic-exporter][0] exposes metrics about Restic snapshots as
Prometheus metrics.  This allows us to get similar data as we have for
BURP backups.  Chiefly important among the metrics are last backup time
and size, which we can use to determine if backups are working
correctly.

[0]: https://github.com/ngosang/restic-exporter
2024-06-26 18:29:49 -05:00
Dustin ebcf9e3d42 authelia: Scale up to 2 replicas
Since Authelia is stateless, we can run a second instance to improve
availability.
2024-06-26 18:29:49 -05:00
Dustin 21e8ad2afd home-assistant: Add commands to control photoframe
The digital photo frame in the kitchen is powered by a server service,
which exposes a minimal HTTP API.  Using this API, we can e.g. advance
or backtrack the displayed photo.  Exposing `rest_command` services
for these operations allows us to add buttons to dashboards to control
the frame.
2024-06-26 18:29:49 -05:00
Dustin 1c4b32925e v-m: Use dynamic discovery for some collectd nodes
We don't need to explicitly specify every single host individually.
Domain controllers, for example, are registered in DNS with SRV records.
Kubernetes nodes, of course, can be discovered using the Kubernetes API.
Both of these classes of nodes change frequently, so discovering them
dynamically is convenient.
2024-06-26 18:29:49 -05:00
Dustin 98651cf9d9 jenkins: Force iSCSI volume on specific nodes
Instead of routing iSCSI traffic from the Kubernetes network, through
the firewall, to the storage network, nodes now have a second network
adapter connected to directly to the storage network.  The nodes with
such an adapter are labelled `network.du5t1n.me/storage`, so we can pin
the Jenkins PersistentVolume to them via a node affinity rule.
2024-06-26 18:29:49 -05:00
Dustin a2225e583e paperless-ngx: Use volume claim template for redis
Using a volume claim template to define the persistent volume claim for
the Redis pod has two advantages: first, it enables using clustered
Redis, if we decide that becomes necessary, and second, it makes
deleteing and recreating the volume easier in the case of data
corruption.  Simply scale down the StatefulSet to 0, delete the PVC, and
scale the StatefulSet back up.
2024-06-26 18:29:49 -05:00
Dustin 02c88700f7 firefly-iii: Use volume claim template for redis
Using a volume claim template to define the persistent volume claim for
the Redis pod has two advantages: first, it enables using clustered
Redis, if we decide that becomes necessary, and second, it makes
deleteing and recreating the volume easier in the case of data
corruption.  Simply scale down the StatefulSet to 0, delete the PVC, and
scale the StatefulSet back up.
2024-06-26 18:29:49 -05:00
Dustin 2ce1821667 step-ca: Allow longer validity for ACME certificates
By default, step-ca issues certificates that are valid for only one day.
This means that clients need to have multiple renew attempts scheduled
throughout the day, otherwise, missing one could mean having their
certificates expire.  This is unnecessary, and not even possible in all
cases, so let's make the default validity period longer and avoid the
issue.
2024-06-26 18:29:49 -05:00
Dustin 858bad55ca grafana: Trust dch-root-ca for LDAP connections
The LDAP servers now use certificates signed by _DCH CA R2_, so the
_DCH Root CA R2_ CA needs to be trusted in order to communicate with
them.
2024-06-26 18:29:49 -05:00
Dustin e71156bcec authelia: Mount dch-root-ca
The LDAP servers now use certificates signed by _DCH CA R2_, so the
_DCH Root CA R2_ CA needs to be trusted in order to communicate with
them.
2024-06-26 18:29:49 -05:00
Dustin b8015c0bed v-m: blackbox: Force TCP probe to IPv4
Since I added an IPv6 ULA prefix to the "main" VLAN (to allow
communicating with the Synology directly), the domain controllers now
have AAAA records.  This causes the `sambadc` screpe job to fail because
Blackbox Exporter prefers IPv6 by default, but Kubernetes pods do not
have IPv6 addreses.
2024-06-26 18:29:49 -05:00
Dustin 7f3287297b jenkins: Migrate to iSCSI persistent volume
Managing the Jenkins volume with Longhorn has become increasingly
problematic.  Because of its large size, whenever Longhorn needs to
rebuild/replicate it (which happens often for no apparent reason), it
can take several hours.  While the synchronization is happening, the
entire cluster suffers from degraded performance.

Instead of using Longhorn, I've decided to try storing the data directly
on the Synology NAS and expose it to Kubernetes via iSCSI.  The Synology
offers many of the same features as Longhorn, including
snapshots/rollbacks and backups.  Using the NAS allows the volume to be
available to any Kubernetes node, without keeping multiple copies of
the data.

In order to expose the iSCSI service on the NAS to the Kubernetes nodes,
I had to make the storage VLAN routable.  I kept it as IPv6-only,
though, as an extra precaution against unauthorized access.  The
firewall only allows nodes on the Kubernetes network to access the NAS
via iSCSI.

I originally tried proxying the iSCSI connection via the VM hosts,
however, this failed because of how iSCSI target discovery works.  The
provided "target host" is really only used to identify available LUNs;
follow-up communication is done with the IP address returned by the
discovery process.  Since the NAS would return its IP address, which
differed from the proxy address, the connection would fail.  Thus, I
resorted to reconfiguring the storage network and connecting directly
to the NAS.

To migrate the contents of the volume, I temporarily created a PVC with
a different name and bound it to the iSCSI PersistentVolume.  Using a
pod with both the original PVC and the new PVC mounted, I used `rsync`
to copy the data.  Once the copy completed, I deleted the Pod and both
PVCs, then created a new PVC with the original name (i.e. `jenkins`),
bound to the iSCSI PV.  While doing this, Longhorn, for some reason,
kept re-creating the PVC whenever I would delete it, no matter how I
requested the deletion.  Deleting the PV, the PVC, or the Volume, using
either the Kubernetes API or the Longhorn UI, they would all get
recreated almost immediately.  Fortunately, there was actually enough of
a delay after deleting it before Longhorn would recreate it that I was
able to create the new PVC manually.  Once I did that, Longhorn seemed
to give up.
2024-06-23 09:53:15 -05:00
Dustin c3c9c0c555 kitchen: Run as non-root user
The *kitchen* server service does not need to run as root or have any
access to writable storage.
2024-06-06 11:03:42 -05:00
Dustin b4d6dfeb07 kitchen: Re-enable graceful shutdown timeout
Version 0.5.1 fixes the issue with `uvicorn` hanging on shutdown because
of the WebSocket message queue.
2024-06-06 10:09:37 -05:00
Dustin 7b8b11111e kitchen: Updates for v0.5
Kitchen v0.5 a few changes that affect the deployment:

* The Bored Board is now backed by MQTT
* The pool temperature is now displayed in the weather pane
* The container image is now based on Fedora and includes its own time
  zone database and root CA bundle
* The websocket server prevents the process from stopping correctly
  unless the graceful shutdown feature of `uvicorn` is disabled
2024-06-05 22:04:55 -05:00
Dustin 48f20eac07 v-m: Scrape metrics from fleetlock 2024-05-31 15:18:55 -05:00
Dustin fc66058251 fleetlock: Deploy Zincati fleet lock manager
[fleetlock] is an implementation of the Zincati FleetLock reboot
coordination protocol.  It only works for machines that are Kubernetes
nodes, but it does enable safe rolling updates for those machines.
Specifically, when a node acquires a lock (backed by a Kubernetes
Lease), it cordons that node and evicts pods from it.  After the node
has rebooted into the new version of Fedora CoreOS, it uncordons the
node and releases the lock.

[fleetlock]: https://github.com/poseidon/fleetlock
2024-05-31 15:18:01 -05:00
Dustin 365334cea7 xactfetch: Provide Vaultwarden password for sync
Vaultwarden has started prompting for the master password occasionally
when syncing the vault.  Thus, we need to make sure it is available in
the _sync_ container, by mounting the secret and providing the
`PINENTRY_PASSWORD_FILE` environment variable.
2024-05-29 09:36:30 -05:00
Dustin 8939c1d02c v-m/scrape: Scrape unifi2.p.b
*unifi2.pyrocufflink.blue* is a Fedora CoreOS host, so it runs
*collectd*, *Promtail*, and *Zincati*.
2024-05-26 11:48:59 -05:00
Dustin 61bfd8ff1a keyserv: Add age keys for unifi2
This key encrypts the password for *unifi_exporter* to connect to Unifi
Network.
2024-05-26 11:48:12 -05:00
Dustin 3b74c3d508 v-m: Scrape metrics from Paperless-ngx Flower 2024-05-22 15:51:07 -05:00
Dustin f83783fd58 paperless-ngx: Enable Flower
Flower is the monitoring agent for Celery.  It has a web UI, but more
importantly, it exposes Celery performance metrics in Prometheus format.
2024-05-22 15:50:32 -05:00
Dustin d5bfdaca25 v-m/alertmanager-ntfy: Add labels to notifications
Just having the alert name and group name in the ntfy notification is
not enough to really indicate what the problem is, as some alerts can
generate notifications for many reasons.  In the email notifications
AlertManager sends by default, the values (but not the keys) of all
labels are included in the subject, so we will reproduce that here.
2024-05-22 15:20:27 -05:00
Dustin aedd4df9f6 sshca: Add machine ID for Toad 2024-05-22 15:20:09 -05:00
Dustin d74e26d527 victoria-metrics: Send alerts via ntfy
I don't like having alerts sent by e-mail.  Since I don't get e-mail
notifications on my watch, I often do not see alerts for quite some
time.  They are also much harder to read in an e-mail client (Fastmail
web an K-9 Mail both display them poorly).  I would much rather have
them delivered via _ntfy_, just like all the rest of the ephemeral
notifications I receive.

Fortunately, it is easy enough to integrate Alertmanager and _ntfy_
using the webhook notifier in Alertmanager.  Since _ntfy_ does not
natively support the Alertmanager webhook API, though, a bridge is
necessary to translate from one data format to the other.  There are a
few options for this bridge, but I chose
[alexbakker/alertmanager-ntfy][0] because it looked the most complete
while also having the simplest configuration format.  Sadly, it does not
expose any Prometheus metrics itself, and since it's deployed in the
_victoria-metrics_ namespace, it needs to be explicitly excluded from
the VMAgent scrape configuration.

[0]: https://github.com/alexbakker/alertmanager-ntfy
2024-05-10 10:32:52 -05:00
Dustin a4591950ba home-assistant: Add time-to-go timer to watch view
This way I can start the "time to go" timer from my watch as soon as
Brandon says he's leaving work.
2024-05-10 09:24:34 -05:00
Dustin ab916640cb home-assistant: Re-enable 17track sensor 2024-05-10 09:24:02 -05:00
Dustin 7618bdcae6 firefly-iii: Replace importer access token
The access token the Firefly III Importer service uses to communicate
with Firefly III expired and needs replaced.
2024-05-10 09:23:04 -05:00
Dustin ebea31fe55 v-m: alerts: Add alert for camera offline 2024-04-23 09:42:04 -05:00
Dustin c2417b7960 authelia: Fix Jenkins OIDC client
Authelia 4.38 introduced a change that broke logging in to Jenkins with
OIDC.  This setting is required to fix it.
2024-04-10 21:26:00 -05:00
Dustin 1581a620ef v-m/scrape: Scrape nvr2.p.b
*nvr2.pyrocufflink.blue* has replaced *nvr1.pyrocufflink.blue* as the
Frigate/recording server.
2024-04-10 21:25:26 -05:00
Dustin c2b595d3e2 keyserv: Add age key for nvr2/NUT monitor 2024-04-06 10:06:30 -05:00
Dustin 31b0b081a3 keyserv: Add key for Frigate/nvr2 2024-04-05 14:12:08 -05:00
Dustin 3ba83373f3 step-ca: Re-deploy (again) with DCH CA R2
Although most libraries support ED25519 signatures for X.509
certificates, Firefox does not.  This means that any certificate signed
by DCH CA R3 cannot be verified by the browser and thus will always
present a certificate error.

I want to migrate internal services that do not need certificates
that are trusted by default (i.e. they are only accessed programatically
or only I use them in the browser) back to using an internal CA instead
of the public *pyrocufflink.net* wildcard certificate.  For applications
like Frigate and UniFi Network, these need to be signed by a CA that
the browser will trust, so the ED25519 certificate is inappropriate.
Thus, I've decided to migrate back to DCH CA R2, which uses an EdDSA
signature, and can therefore be trusted by Firefox, etc.
2024-04-05 13:03:34 -05:00
Dustin 5c34fdb1c6 sshca: Add Machine UUID for nvr2.p.b 2024-04-05 12:26:51 -05:00
Dustin 680709e670 authelia: Add auth rule for HLC forms submit
The *hlcforms* application handles form submissions for the Hatch
Learning Center website.  It has various features for Tabitha that are
only accessible internally, but the form submission handler itself of
course needs to be accessible anonymously.
2024-03-25 08:43:55 -05:00
Dustin c7223ff4fd authelia: Enable dark theme
A recent version of *Authelia* added a dark theme.  Setting the `theme`
option to `auto` enables it when the user agent has the "prefers dark
mode" hint enabled.
2024-02-27 06:51:14 -06:00
Dustin de72776e73 v-m: Scrape metrics from Authelia
Authelia exposes Prometheus metrics from a different server socket,
which is not enabled by default.
2024-02-27 06:41:52 -06:00
Dustin e0b2b3f5ae v-m: Scrape metrics from Patroni
Patroni, a component of the *postgres poerator*, exports metrics about
the PostgreSQL database servers it manages.  Notably, it provides
information about the current transaction log location for each server.
This allows us to monitor and alert on the health of database replicas.
2024-02-24 08:33:52 -06:00
Dustin 2442835edd autoscaler: Add SealedSecret for AWS key 2024-02-22 09:59:16 -06:00
Dustin 83eeb46c93 v-m: Scrape Argo CD
*Argo CD* exposes metrics about itself and the applications it manages.
Notibly, this can be useful for monitoring application health.
2024-02-22 07:10:01 -06:00
Dustin 465f121e61 v-m: Scrape Promtail
The *promtail* job scrapes metrics from all the hosts running Promtail.
The static targets are Fedora CoreOS nodes that are not part of the
Kubernetes cluster.

The relabeling rules ensure that both the static targets and the
targets discovered via the Kubernetes Node API use the FQDN of the host
as the value of the *instance* label.
2024-02-22 07:10:01 -06:00
Dustin 815eefdcf9 promtail: Deploy as DaemonSet
Running Promtail in a pod controlled by a DaemonSet allows it to access
the Kubernetes API via a ServiceAccount token.  Since it needs the API
in order to discover the Pods running on the current node in order to
find their log files, this makes the authentication process a lot
simpler.
2024-02-22 07:10:01 -06:00
Dustin 5e4ab1d988 v-m: Update Loki scrape target
Now that Loki uses Caddy as a reverse proxy, we need to update the
scrape target to point to the correct port (443).
2024-02-22 07:10:01 -06:00
Dustin f468977d91 grafana: Enable send_user_header option
I discovered today that if anonymous Grafana users have Viewer
permission, they can use the Datasource API to make arbitrary queries
to any backend, even if they cannot access the Explore page directly.
This is documented ([issue #48313][0]) as expected behavior.

I don't really mind giving anonymous access to the Victoria Metrics
datasource, but I definitely don't want anonymous users to be able to
make Loki queries and view log data.  Since Grafana Datasource
Permissions is limited to Grafana Enterprise and not available in
the open source version of Grafana, the official recommendation from
upstream is to use a separate Organization for the Loki datasource.
Unfortunately, this would preclude having dashboards that have graphs
from both data sources.  Although I don't have any of those right now, I
like the idea and may build some eventually.

Fortunately, I discovered the `send_user_header` Grafana configuration
option.  With this enabled, Grafana will send an `X-Grafana-User` header
with the username of the user on whose behalf it is making a request to
the backend.  If the user is not logged in, it does not send the header.
Thus, we can detect the presence of this header on the backend and
refuse to serve query requests if it is missing.

[0]: https://github.com/grafana/grafana/issues/48313
2024-02-22 07:10:01 -06:00
Dustin 35ff500812 grafana: Configure Loki datastore
Usually, Grafana datastores are configured using its web GUI.  When
setting up a datastore that requires TLS client authentication, the
client certificate and private key have to be pasted into the form.
For certificates that renew frequently, this method would require a
frequent manual effort.  Fortunately, Grafana supports defining
datastores via its "provisioning" mechanism, reading the configuration
from YAML files on the filesystem.
2024-02-22 07:10:01 -06:00
Dustin d4efb735bf loki-ca: Add cert-manager issuer for Loki CA
The Loki CA is used to issue client certificates for Grafana Loki.  This
_cert-manager_ ClusterIssuer will allow applications running in
Kubernetes (e.g. Grafana) to request a Certificate that they can use to
access the Loki HTTP API.
2024-02-22 07:10:01 -06:00
Dustin d08cc6fb0f step-ca: Redeploy with DCH CA R3
I never ended up using _Step CA_ for anything, since I was initially
focused on the SSH CA feature and I was unhappy with how it worked
(which led me to write _SSHCA_).  I didn't think about it much until I
was working on deploying Grafana Loki.  For that project, I wanted to
use a certificate signed by a private CA instead of the wildcard
certificate for _pyrocufflink.blue_.  So, I created *DCH CA R3* for that
purpose.  Then, for some reason, I used the exact same procedure to
fetch the certificate from Kubernetes as I had set up for the
_pyrocufflink.blue_ wildcard certificate, as used by Frigate.  This of
course defeated the purpose, since I could have just as easily used
the wildcard certificate in that case.

When I discovered that Grafana Loki expects to be deployed behind a
reverse proxy in order to implement access control, I took the
opportunity to reevaluate the certificate issuance process.  Since a
reverse proxy is required to implement the access control I want (anyone
can push logs but only authenticated users can query them), it made
sense to choose one with native support for requesting certificates via
ACME.  This would eliminate the need for `fetchcert` and the
corresponding Kubernetes API token.  Thus, I ended up deciding to
redeploy _Step CA_ with the new _DCH CA R3_ for this purpose.
2024-02-22 07:10:01 -06:00
Dustin 4c238a69aa v-m: Scrape Grafana Loki
Grafana Loki is hosted on a VM named *loki0.pyrocufflink.blue*.  It runs
Fedora CoreOS, so in addition to scraping Loki itself, we need to scrape
_collectd_ and _Zincati_ as well.
2024-02-21 09:16:26 -06:00
Dustin 1777262c15 dch-root-ca: Update to DCH Root CA R3
Since I shut down _step-ca_, nothing uses _DCH Root CA R2_ anymore.
I've created a new CA using ED25519 key pairs, named _DCH Root CA R3_.
2024-02-21 09:16:26 -06:00
Dustin 1d2b5260bb keyserv: Add age key for loki0
This key is used to encrypt the Kubernetes access token for `fetchcert`,
which downloads the certificate for Grafana Loki HTTPS.
2024-02-21 09:16:26 -06:00
Dustin 96928a2611 kitchen: Fix weather metrics API URI
Apparently, I never bothered to check that the Kitchen HUD server was
actually fetching data from Victoria Metrics when I updated it before; I
only verified that the Unauthorized errors in the `vmselect` log
went away.  They did, but only because now the Kitchen server was
failing to contact `vmselect` at all.
2024-02-21 08:01:35 -06:00
Dustin 2acefd9a72 v-m: Add alert for sensor battery levels
I did not realize the batteries on the garage door tilt sensors had
died.  Adding alerts for various sensor batteries should help keep me
better informed.
2024-02-16 20:56:38 -06:00
Dustin 9784b90743 cert-manager: Remove unused secrets
These secrets were used by previous issuers/solvers and are no longer
needed.
2024-02-16 20:56:08 -06:00
Dustin 0ad63e0613 authelia: Allow anonymous access to AlertManager
Sometimes, I want to be able to look at active alerts without logging
in.  This rule allows read-only access to the AlertManager UI and API.
Unfortunately, the user experience when attempting to create a new
Silence using the UI without first logging in is suboptimal, but I think
that's worth the trade-off.
2024-02-16 20:41:47 -06:00
Dustin 2f6c358860 invoice-ninja: Update PVC for restored backup
The Longhorn volume for the *invoice-ninja* PVC got into a strange state
following an unexpected shutdown this morning.  One of its replicas
seemed to have disappeared, and it also thought that the size had
changed.  As such, it got stuck in "expanding" state, but it was not
actually being expanded.  This issue is described in detail in the
Longhorn documentation: [Troubleshooting: Unexpected expansion leads to
degradation or attach failure][0].  Unfortunately, there is no way to
recover a volume from that state, and it must be deleted and recreated
from backup.  This changes some of the properties of the PVC, so they
need to be updated in the manifest.

[0]: https://longhorn.io/kb/troubleshooting-unexpected-expansion-leads-to-degradation-or-attach-failure/
2024-02-15 09:45:57 -06:00
Dustin 80df160ceb device-plugins: Allow FUSE plugin on Jenkins nodes
Jenkins jobs that build container images need access to `/dev/fuse`.
Thus, we have to allow Pods managed by the *fuse-device-plugin*
DaemonSet to be scheduled on nodes that are tainted for use exclusively
by Jenkins jobs.
2024-02-13 07:56:35 -06:00
Dustin 33fa951c68 Merge remote-tracking branch 'refs/remotes/origin/master' 2024-02-03 09:52:39 -06:00
Dustin a395d176bc sshca: Set group principals for Server Admins
Members of the *Server Admins* group need to be able to log in to
machines using their respective privileged accounts for e.g.
provisioning or emergencies.
2024-02-02 21:02:40 -06:00
Dustin 1f28a623ae v-m: Do not scrape/alert on Graylog
Graylog is down because Elasticsearch corrupted itself again, and this
time, I'm just not going to bother fixing it.  I practically never use
it anymore anyway, and I want to migrate to Grafana Loki, so now seems
like a good time to just get rid of it.
2024-02-01 21:45:43 -06:00
Dustin 380af211ec authelia: Reduce log level 2024-02-01 21:36:27 -06:00
Dustin 94300ac502 kitchen: Use SealedSecret template for config
The configuration file for the kitchen HUD server has credentials
embedded in it.  Until I get around to refactoring it to read these from
separate locations, we'll make use of the template feature of
SealedSecrets.  With this feature, fields can refer to the (decrypted)
value of other fields using Go template syntax.  This makes it possible
to have most of the `config.yaml` document unencrypted and easily
modifiable, while still protecting the secrets.
2024-02-01 21:18:46 -06:00
Dustin baab02217e authelia: Remove rule for Paperless-ngx API
I don't like the [Paperless Mobile][0] app well enough to remove the MFA
restriction for the Paperless-ngx API.

[0]: https://github.com/astubenbord/paperless-mobile
2024-02-01 21:17:46 -06:00
Dustin 2cd4a8b097 sshca: Configure user CA
SSHCA now supports issuing user certificates.  It uses OpenID Connect to
authenticate requests, and issues certificates based on the user's ID
token.
2024-02-01 09:02:11 -06:00
Dustin 834d0f804f v-m: Scrape Grafana
Grafana exports Prometheus metrics about its own performance.
2024-02-01 09:02:01 -06:00
Dustin 3439ce1f13 grafana: Deploy Grafana
Now that Victoria Metrics is hosted in Kubernetes, it only makes sense
to host Grafana there as well.  I chose to use a single-instance
deployment for simplicity; I don't really need high availability for
Grafana.  Its configuration does not change enough to worry about the
downtime associated with restarting it.  Migrating the existing data
from SQLite to PostgreSQL, while possible, is just not worth the hassle.
2024-01-27 22:01:08 -06:00
Dustin 4e15a9d71d invoice-ninja: Deploy Invoice Ninja
Invoice Ninja is a small business management tool.  Tabitha wants to
use it for HLC.

I am a bit concerned about the code quality of this application, and
definitely alarmed at the data it send upstream, so I have tried to be
extra careful with it.  All privileges are revoked, including access to
the Internet.
2024-01-27 21:11:26 -06:00
Dustin a5d186b461 sshca: Add update-machine-ids script
The `update-machine-ids.sh` shell script helps update the `sshca-data`
SealedSecret with the current contents of the `machine-ids.json` file
(stored locally, not tracked in Git).
2024-01-25 20:42:47 -06:00
Dustin 8ae8bad112 v-m: Scrape serial1.p.b 2024-01-25 20:42:07 -06:00
Dustin 7eae328a2c sshca: Add machine ID for serial1.p.b 2024-01-25 20:41:54 -06:00
Dustin 9fff21aae1 h-a: Remove roomba_is_downstairs template sensor
This sensor is now provided by a [Threshold][0] helper.

[0]: https://www.home-assistant.io/integrations/threshold/
2024-01-25 17:31:36 -06:00
Dustin 8bb8ed4402 xactfetch: Additional mounts for rbw sync
In order to sync the Bitwarden vault, `rbw` needs its configuration file
in `/etc/rbw` and access to writable ephemeral storage at `/tmp`.
2024-01-24 12:00:13 -06:00
Dustin ad37948fe2 v-m: Scrape all metrics components
We are now getting metrics from *vmstorage*, *vminsert*, *vmselect*,
*vmalert*, *alertmanaer*, and *blackbox-exporter*, in addition to
*vmagent*.
2024-01-23 11:51:50 -06:00
Dustin bcb588407d v-m: Correct vmalert remote read/write URLs
*vmalert* has been generating alerts and triggering notifications, but
not writing any `ALERTS`/`ALERTS_FOR_STATE` metrics.  It turns out this
is because I had not correctly configured the remote read/write
URLs.
2024-01-23 10:45:40 -06:00
Dustin 9a76a548ec argocd/app: jenkins: Enable auto sync
We're going to try out automatically synchronizing the Jenkins resources
when changes are pushed to Git.
2024-01-22 18:50:41 -06:00
Dustin 119a8a74ae v-m: alerts: Enhance Frigate unavailable alert
If Frigate is running but not connected to the MQTT broker, the
`sensor.frigate_status` entity will be available, but the
`update.frigate_server` entity will not.
2024-01-22 18:27:30 -06:00
Dustin 20ef2a287b jenkins: Update to 2.426.2 2024-01-22 18:01:03 -06:00
277 changed files with 9755 additions and 7526 deletions

94
20125/config.yml Normal file
View File

@ -0,0 +1,94 @@
alertmanager:
url: http://alertmanager.victoria-metrics:9093
system_wide:
alerts:
- alertgoup: Active Directory
- alertgoup: Longhorn
- alertgoup: PostgreSQL
- alertgoup: Restic
- alertgoup: Temperature
- job: authelia
- job: blackbox
- job: dns_pyrocufflink
- job: dns_recursive
- job: kubelet
- job: kubernetes
- job: minio-backups
- instance: db0.pyrocufflink.blue
- instance: gw1.pyrocufflink.blue
- instance: vmhost0.pyrocufflink.blue
- instance: vmhost1.pyrocufflink.blue
applications:
- name: Home Assistant
url: https://homeassistant.pyrocufflink.blue/
icon:
url: icons/home-assistant.svg
alerts:
- alertgroup: Home Assistant
- alertgroup: Frigate
- job: homeassistant
- instance: homeassistant.pyrocufflink.blue
- name: Nextcloud
url: &url0 https://nextcloud.pyrocufflink.net/index.php
icon:
url: icons/nextcloud.png
alerts:
- instance: *url0
- instance: cloud0.pyrocufflink.blue
- name: Invoice Ninja
url: &url1 https://invoiceninja.pyrocufflink.net/
icon:
url: icons/invoiceninja.svg
class: light-bg
alerts:
- instance: *url1
- name: Jellyfin
url: https://jellyfin.pyrocufflink.net/
icon:
url: icons/jellyfin.svg
alerts:
- job: jellyfin
- name: Vaultwarden
url: &url2 https://bitwarden.pyrocufflink.net/
icon:
url: icons/vaultwarden.svg
class: light-bg
alerts:
- instance: *url2
- alertgroup: Bitwarden
- name: Paperless-ngx
url: &url3 https://paperless.pyrocufflink.blue/
icon:
url: icons/paperless-ngx.svg
alerts:
- instance: *url3
- alertgroup: Paperless-ngx
- job: paperless-ngx
- name: Firefly III
url: &url4 https://firefly.pyrocufflink.blue/
icon:
url: icons/firefly-iii.svg
alerts:
- instance: *url4
- name: Receipts
url: &url5 https://receipts.pyrocufflink.blue/
icon:
url: https://receipts.pyrocufflink.blue/static/icons/icon-512.png
alerts:
- instance: *url5
- name: Music Assistant
url: &url6 https://music.pyrocufflink.blue/
icon:
url: https://music.pyrocufflink.blue/apple-touch-icon.png
alerts:
- instance: *url6

25
20125/ingress.yaml Normal file
View File

@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
cert-manager.io/issuer: status-server-ca
labels: &labels
app.kubernetes.io/name: status-server
name: status-server
spec:
tls:
- hosts:
- 20125.home
secretName: status-server-cert
rules:
- host: 20125.home
http:
paths:
- backend:
service:
name: status-server
port:
number: 80
path: /
pathType: Prefix

26
20125/kustomization.yaml Normal file
View File

@ -0,0 +1,26 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: '20125'
labels:
- pairs:
app.kubernetes.io/instance: '20125'
app.kubernetes.io/part-of: '20125'
includeSelectors: true
resources:
- namespace.yaml
- secrets.yaml
- status-server-ca.yaml
- status-server.yaml
- ingress.yaml
configMapGenerator:
- name: 20125-config
files:
- config.yml
images:
- name: git.pyrocufflink.net/packages/20125.home
newTag: dev

6
20125/namespace.yaml Normal file
View File

@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: "20125"
labels:
app.kubernetes.io/name: '20125'

13
20125/secrets.yaml Normal file
View File

@ -0,0 +1,13 @@
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: imagepull-gitea
namespace: "20125"
spec:
encryptedData:
.dockerconfigjson: AgAXY5XsnGF9E3RU9dnKXK9fWjqK0khCDf7n0vuJCLACrcM01aoWVSjl26+j7oSTTyc7t5C+EKPJnuKdlkNfh2Omw9Lh3dn8rPRYcBRmUEAyt0TvBVkxBIiP+49y39QEV1opYY+b1gLVJ5ZEC92u5uI9y8xovwx9wqtKLfQ+KCfc5m93AYaQJ9EcnV1DSEkv/HdtWNikQes2hO6pTLF/GHrh/s79eIeXMTm5oG/OyJWTOGQdy1SdoGWLLf31dsjhsJyGMYOtWx42Nou20lWqmdoy4Dd8OXuuhcfeDNzkH187mI4XpVjbS0M+P5teJsGiTwx+VyJlGQnEaquIiHy3KLt3YH/ltGeNeCNbFmSDa70A3IdP/t0cAXN20rlIFGVzqNrAOhMYtiTDEgaKOrL7mwM4i4NTCnLTA2nXU7gLEcLGPRqO7LKIhc1/6d1xWMT58SFjHAVklFt/lq1udY6zE8gXHp+RQ+7hIIEu500YiaKubvh2MsOKIqYOaX99Q4BW7PQhwjjwtFHFuwNjZn8wAbDq+3gsDSqgeFPgHAs7nPIImcBne/fTobsHhUVvxEnBNLCRtSqpkvOLzpgC+dRNsD6ZTcXPhFWTEOvjBMcUWqOTcRmd8DCsdxalM42x/ZQjlNlubZeuaNki+4pA80bYlsLWt3A2nWtcVbO/aAYrT1qiK/d8NZsPNidD0HE1rkUkCNv5KgXVWUfVU7ptX1YFpYXXuEIFeWzulH3gWmdW4q+t2nGHAqwkszZfijtpsexBttff1ym3rgBTGHFmQRkmSMbNHIAq29ehuVrxkH7uM8Q1cXXmMnGgre0ijtUfW9zMlx92jR86187xOLM3/hxANhfyt4eZVMwx8D42facMxxAngCi01vYTwqihA9mtBFkKlkQdKCH1NxgWQqwAJi87utgHoFivxeM+Pck7Zeottr0yzUEisdoBAdQR99hijR2C5SnC4iURnqfi9sloj0Uuo74SxiTGapA7pg77LmvpV9Wzu6QiEm944tftcZHwaMg=
template:
metadata:
name: imagepull-gitea
namespace: "20125"
type: kubernetes.io/dockerconfigjson

View File

@ -0,0 +1,32 @@
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-ca
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: status-server-ca
spec:
isCA: true
commonName: 20125 CA
secretName: status-server-ca-secret
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-ca
kind: Issuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: status-server-ca
spec:
ca:
secretName: status-server-ca-secret

51
20125/status-server.yaml Normal file
View File

@ -0,0 +1,51 @@
apiVersion: v1
kind: Service
metadata:
labels: &labels
app.kubernetes.io/name: status-server
app.kubernetes.io/component: status-server
name: status-server
spec:
ports:
- port: 80
protocol: TCP
targetPort: 20125
selector: *labels
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels: &labels
app.kubernetes.io/name: status-server
app.kubernetes.io/component: status-server
name: status-server
spec:
replicas: 1
selector:
matchLabels: *labels
template:
metadata:
labels: *labels
spec:
containers:
- name: status-server
image: git.pyrocufflink.net/packages/20125.home
imagePullPolicy: Always
env:
- name: RUST_LOG
value: info,status_server=debug
volumeMounts:
- mountPath: /usr/local/share/20125.home/config.yml
name: config
subPath: config.yml
readOnly: True
nodeSelector:
kubernetes.io/arch: amd64
imagePullSecrets:
- name: imagepull-gitea
volumes:
- name: config
configMap:
name: 20125-config

2
ansible/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
ara/.secrets.toml
host-provisioner.key

88
ansible/ara.yaml Normal file
View File

@ -0,0 +1,88 @@
apiVersion: v1
kind: Service
metadata:
name: ara
labels: &labels
app.kubernetes.io/name: ara
app.kubernetes.io/component: ara
spec:
selector: *labels
type: ClusterIP
ports:
- name: http
port: 8000
targetPort: 8000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ara
labels: &labels
app.kubernetes.io/name: ara
app.kubernetes.io/component: ara
spec:
selector:
matchLabels: *labels
template:
metadata:
labels: *labels
spec:
enableServiceLinks: false
containers:
- name: ara-api
image: quay.io/recordsansible/ara-api
imagePullPolicy: IfNotPresent
env:
- name: ARA_BASE_DIR
value: /etc/ara
- name: ARA_SETTINGS
value: /etc/ara/settings.toml
- name: SECRETS_FOR_DYNACONF
value: /etc/ara/.secrets.toml
ports:
- containerPort: 8000
name: http
readinessProbe: &probe
httpGet:
port: 8000
path: /api/
httpHeaders:
- name: Host
value: ara.ansible.pyrocufflink.blue
failureThreshold: 3
periodSeconds: 60
successThreshold: 1
timeoutSeconds: 5
startupProbe:
<<: *probe
failureThreshold: 30
initialDelaySeconds: 1
periodSeconds: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /etc/ara/settings.toml
name: config
subPath: settings.toml
readOnly: true
- mountPath: /etc/ara/.secrets.toml
name: secrets
subPath: .secrets.toml
readOnly: true
- mountPath: /tmp
name: tmp
subPath: tmp
securityContext:
runAsNonRoot: true
runAsUser: 7653
runAsGroup: 7653
volumes:
- name: config
configMap:
name: ara
- name: secrets
secret:
secretName: ara
- name: tmp
emptyDir:
medium: Memory

38
ansible/ara/settings.toml Normal file
View File

@ -0,0 +1,38 @@
[default]
ALLOWED_HOSTS = [
'ara.ansible.pyrocufflink.blue',
]
LOG_LEVEL = 'INFO'
TIME_ZONE = 'UTC'
EXTERNAL_AUTH = true
READ_LOGIN_REQUIRED = false
WRITE_LOGIN_REQUIRED = false
DATABASE_ENGINE = 'django.db.backends.postgresql'
DATABASE_HOST = 'postgresql.pyrocufflink.blue'
DATABASE_NAME = 'ara'
DATABASE_USER = 'ara'
[default.DATABASE_OPTIONS]
sslmode = 'verify-full'
sslcert = '/run/secrets/ara/postgresql/tls.crt'
sslkey = '/run/secrets/ara/postgresql/tls.key'
sslrootcert = '/run/dch-ca/dch-root-ca.crt'
[default.LOGGING]
version = 1
disable_existing_loggers = false
[default.LOGGING.formatters.normal]
format = '%(levelname)s %(name)s: %(message)s'
[default.LOGGING.handlers.console]
class = 'logging.StreamHandler'
formatter = 'normal'
level = 'INFO'
[default.LOGGING.loggers.ara]
handlers = ['console']
level = 'INFO'
propagate = false

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoOO/ZYMxRgmyvqZwGN3NM5pHyh3NBdC7iZrXIopt93 Host Provisioner

32
ansible/ingress.yaml Normal file
View File

@ -0,0 +1,32 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ara
labels:
app.kubernetes.io/name: ara
app.kubernetes.io/component: ara
annotations:
cert-manager.io/cluster-issuer: dch-ca
nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"
nginx.ingress.kubernetes.io/auth-method: GET
nginx.ingress.kubernetes.io/auth-url: http://authelia.authelia.svc.cluster.local:9091/api/verify
nginx.ingress.kubernetes.io/auth-signin: https://auth.pyrocufflink.blue/?rm=$request_method
nginx.ingress.kubernetes.io/auth-snippet: |
proxy_set_header X-Forwarded-Method $request_method;
spec:
ingressClassName: nginx
tls:
- hosts:
- ara.ansible.pyrocufflink.blue
secretName: ara-cert
rules:
- host: ara.ansible.pyrocufflink.blue
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ara
port:
name: http

View File

@ -0,0 +1,71 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
transformers:
- |
apiVersion: builtin
kind: NamespaceTransformer
metadata:
name: namespace-transformer
namespace: ansible
unsetOnly: true
setRoleBindingSubjects: allServiceAccounts
fieldSpecs:
- path: metadata/namespace
create: true
labels:
- pairs:
app.kubernetes.io/instance: ansible
includeSelectors: true
includeTemplates: true
- pairs:
app.kubernetes.io/part-of: ansible
resources:
- ../dch-root-ca
- ../ssh-host-keys
- rbac.yaml
- secrets.yaml
- namespace.yaml
- ara.yaml
- postgres-cert.yaml
- ingress.yaml
configMapGenerator:
- name: ara
files:
- ara/settings.toml
options:
labels:
app.kubernetes.io/name: ara
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: ara
spec:
template:
spec:
containers:
- name: ara-api
volumeMounts:
- mountPath: /run/dch-ca/dch-root-ca.crt
name: dch-root-ca
subPath: dch-root-ca.crt
readOnly: true
- mountPath: /run/secrets/ara/postgresql
name: postgresql-cert
readOnly: true
securityContext:
fsGroup: 7653
volumes:
- name: postgresql-cert
secret:
secretName: ara-postgres-cert
defaultMode: 0640
- name: dch-root-ca
configMap:
name: dch-root-ca

6
ansible/namespace.yaml Normal file
View File

@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: ansible
labels:
app.kubernetes.io/name: ansible

View File

@ -0,0 +1,12 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ara-postgres-cert
spec:
commonName: ara
privateKey:
algorithm: ECDSA
secretName: ara-postgres-cert
issuerRef:
name: postgresql-ca
kind: ClusterIssuer

170
ansible/rbac.yaml Normal file
View File

@ -0,0 +1,170 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dch-webhooks
rules:
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dch-webhooks
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dch-webhooks
subjects:
- kind: ServiceAccount
name: dch-webhooks
namespace: default
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: host-provisioner
labels:
app.kubernetes.io/name: host-provisioner
app.kubernetes.io/component: host-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: host-provisioner
namespace: kube-public
annotations:
kubernetes.io/description: >-
Allows the host-provisioner to access the _cluster-info_ ConfigMap,
which it uses to get the connection details for the Kubernetes API
server, including the issuing CA certificate, to pass to `kubeadm
join` on a new worker node.
rules:
- apiGroups:
- ''
resources:
- configmaps
verbs:
- get
resourceNames:
- cluster-info
- kube-root-ca.crt
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: host-provisioner
annotations:
kubernetes.io/description: >-
Allows the host-provisioner to manipulate labels, taints, etc. on
nodes it adds to the cluster.
rules:
- apiGroups:
- ''
resources:
- nodes
verbs:
- get
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: host-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: host-provisioner
subjects:
- kind: ServiceAccount
name: host-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: host-provisioner
namespace: kube-system
annotations:
kubernetes.io/description: >-
Allows the host-provisioner to create bootstrap tokens in order to
add new nodes to the Kubernetes cluster.
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- create
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: host-provisioner
namespace: kube-public
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: host-provisioner
subjects:
- kind: ServiceAccount
name: host-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: host-provisioner
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: host-provisioner
subjects:
- kind: ServiceAccount
name: host-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: host-provisioner
namespace: victoria-metrics
annotations:
kubernetes.io/description: >-
Allows the host-provisioner to update the scrape-collectd
ConfigMap when adding new hosts.
rules:
- apiGroups:
- ''
resources:
- configmaps
verbs:
- patch
- get
resourceNames:
- scrape-collectd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: host-provisioner
namespace: victoria-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: host-provisioner
subjects:
- kind: ServiceAccount
name: host-provisioner

37
ansible/secrets.yaml Normal file
View File

@ -0,0 +1,37 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: ara
namespace: ansible
labels:
app.kubernetes.io/name: ara
app.kubernetes.io/component: ara
spec:
encryptedData:
.secrets.toml: AgAiObM2t8Cmr87pMRhZN4RBqb4soEdG0OJeAmaUCl//in2LihZyOHKu5RDeLBaPneoX5G/t5eQX7KkPCW7hffjBSngVbPMZ+U8Txb1IY3uFFHGAPnJBXwHo6FgRq5uKt3LQ6UmtWLoIF4ZB4K0f/g5BHR3N6FIah/x5pKrnU9lOltVgDFSEd7Ewgrj8AorASdE7ZxBAGuUPNktQZZ9MS0d2YiOhgfZiGHDnLZoqk0osDOZzKJX47yiYg5SR4NHoGzd7gfSvBtbrU4SIQCUGZJYtOKeUGaNtCgKnLe3oCphqV3izUY1JudVF8eN5MDgUH5vG2GcqDqMYTX2oRuk+rgRjiMJTkxQ/OZlbrXGxUocTR51EoM01vgjvvCsqaE3R5MhcKE7oOHrqTXzhDY6UzBPUu6QWrkWWMegBeIVCWA2ID3m8CPljyA0oZuClqVZpx/23cs3aHcyl2vye5ey3ca5QzLkkmKK7826H3przUYdwti9gMNp0sPszsDOTzfmN9iZD33a+WvEPfbf7+ZBXBAnoH06pLXeCGc43Q2S619xdHRw4caVGeczZAWYVjlnq8BUQGmHU2Ra5W6dzYM+i3vUimJRiuzeaG+APgY4KIdZNEjPguiwg93g9NtDWgap1h5rF3Yx4nEQelEN0pNAqT8CP67gW1Kp+wjNRNHkz45Ld3mJbMsvFqjZG5cCqk1s67mBNxhani0HBJM3vEV36wnDBzWwSmemuMUdjrG0zFwQHHeZwQe7oR+9XNz1DLPxvvp6KfEbHA3YMagQa2RYxN/C9APBBC+dmk6+TJn1n
template:
metadata:
name: ara
namespace: ansible
labels:
app.kubernetes.io/name: ara
app.kubernetes.io/component: ara
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: provisioner-ssh-key
namespace: ansible
labels: &labels
app.kubernetes.io/name: provisioner-ssh-key
app.kubernetes.io/component: host-provisioner
spec:
encryptedData:
host-provisioner.key: AgCiBQEtPmzQO9GHoVxZNQmjFn9GjeKWlHmG2lz4uqeva77QByqnejUg8CbpQnoT61ct9o39tVtrrHgC8WjseXKGKkd+YELRaWENXBNBFlv4YN6id2iPzf4xHrgfowXLjzly7s4s4Fg3QntXFglQxwG009Z7K5HQmAvgCFzGm6y+fyLoNd2v2eNc9pGurynnm7wKQFuBBpBtoDVfYMNSS+tp9D3MFVMwEG8kU/kszv5OEEwVkipG4v2LeY86HXIQnHyeE3vITz0TFPoQjpjusBNg7MxBVHcz/ZruqF43DZ+uz2aRFL6D5udm86hsxZGSi3yVq8PSCUANtWoTicIpSc5yxpB+5FLsc3Q380vQPrRYvx8luAZwMGQPDv2NpGoSRUmutb/+4vpQbCBwaP9s8WHaYNDByUeoQKAX2o+RYp+/csfxmSy1/pK93RUjMnsWGYiyI7jpNdTqWkakDN+cM0Lrje9+VqcZge3FYp/4y78AI75pWEiEMy1VSXeqE2pgu5vZzyRdw9zORC2sAWhnTeu+Obbly1UdptpXPmGclmRbpwAPM1F7m7pDsCQ9SYAhoGg251Yu0sF3Nnc0uOElmP0KSn1bt/Jca9M0syg9DMntHo41dn40+Aihujej0ll4h3GXVZ0auUuzSLZEMe0dHQY0YCaq3JdeOa6AJuNyo63/0BmvmWP2T06INtVw4EqBsmvNl/YJIlZiRGhIOGaRyJllu21L6QBtToYjxI7fhTxZaCG6fyPbvCd1hu+IchoMr86rl7W0+k6d/lkamx9dg+PtWjjThOGyeLYwSRhMcsvQPsSdTl8BEmB9TRgRIk42txVRQkb+ei1+1y9nBYCOV9P540lDXQVbqgyb0j2cccWOa/AG7l3P3s8haDs2OujUaVkBJWJ489nsLsC33972wwAQbOk+uTKmXKL6nWSNL31rivW9R8ea+vfdcyN2/tLsI0mE9XTR/kRmS12qdLmDbzeX/scqSKaWFQZwnLHak5Xaqkd25ZGHqB3zrnTBIryDaXSzgC1CPCv7QNqbKvd6vmH+16j1DWqLycbUeorx5O9nwpEZ+GzQm8q62PJEO8xdvqr3nu5OvFgGrnX/Y6giV8Cv8ogyAxbmNrq0cC5VYxDlt4VvzlOpmWUlfxD/wd+gaHQoibhhHRbGtsJCX9AFclVQrY3kmduTi/iJlTTJjMQKm9JJRXKbNDxH+B25Zj/hUIC1/NNZOSDn654Pi/yOGXITp86j9unfnIXdJPg=
template:
metadata:
name: provisioner-ssh-key
namespace: ansible
labels: *labels

View File

@ -11,3 +11,6 @@ spec:
path: authelia path: authelia
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -0,0 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: csi-synology
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
path: democratic-csi
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -11,3 +11,6 @@ spec:
path: firefly-iii path: firefly-iii
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -0,0 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: grafana
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
path: grafana
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -11,3 +11,6 @@ spec:
path: home-assistant path: home-assistant
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -0,0 +1,13 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: invoice-ninja
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
path: invoice-ninja
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master

View File

@ -11,3 +11,7 @@ spec:
path: jenkins path: jenkins
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master targetRevision: master
syncPolicy:
automated:
prune: true
selfHeal: true

View File

@ -11,3 +11,6 @@ spec:
path: ntfy path: ntfy
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -11,3 +11,6 @@ spec:
path: paperless-ngx path: paperless-ngx
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -0,0 +1,18 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: &name receipts
namespace: argocd
labels:
vendor: dustin
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
path: *name
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -1,13 +1,13 @@
apiVersion: argoproj.io/v1alpha1 apiVersion: argoproj.io/v1alpha1
kind: Application kind: Application
metadata: metadata:
name: postgresql name: step-ca
namespace: argocd namespace: argocd
spec: spec:
destination: destination:
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
project: default project: default
source: source:
path: postgresql path: step-ca
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master targetRevision: master

View File

@ -0,0 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: vaultwarden
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
path: vaultwarden
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master
syncPolicy:
automated:
prune: true

View File

@ -24,6 +24,66 @@ configMapGenerator:
- policy.csv - policy.csv
patches: patches:
- patch: |-
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: argocd-application-controller
spec:
template:
spec:
containers:
- name: argocd-application-controller
imagePullPolicy: IfNotPresent
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-notifications-controller
spec:
template:
spec:
containers:
- name: argocd-notifications-controller
imagePullPolicy: IfNotPresent
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-redis
spec:
template:
spec:
containers:
- name: redis
imagePullPolicy: IfNotPresent
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-repo-server
spec:
template:
spec:
containers:
- name: argocd-repo-server
imagePullPolicy: IfNotPresent
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-server
spec:
template:
spec:
containers:
- name: argocd-server
imagePullPolicy: IfNotPresent
- patch: |- - patch: |-
$patch: delete $patch: delete
apiVersion: apiextensions.k8s.io/v1 apiVersion: apiextensions.k8s.io/v1

View File

@ -54,7 +54,7 @@ spec:
- name: authelia - name: authelia
image: ghcr.io/authelia/authelia image: ghcr.io/authelia/authelia
env: env:
- name: AUTHELIA_JWT_SECRET_FILE - name: AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE
value: /run/authelia/secrets/jwt.secret value: /run/authelia/secrets/jwt.secret
- name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE - name: AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE
value: /run/authelia/secrets/ldap.password value: /run/authelia/secrets/ldap.password
@ -66,6 +66,13 @@ spec:
value: /run/authelia/secrets/oidc.hmac_secret value: /run/authelia/secrets/oidc.hmac_secret
- name: AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE - name: AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE
value: /run/authelia/secrets/oidc.issuer_private_key value: /run/authelia/secrets/oidc.issuer_private_key
ports:
- containerPort: 9091
name: http
protocol: TCP
- containerPort: 9959
name: metrics
protocol: TCP
startupProbe: startupProbe:
httpGet: httpGet:
port: 9091 port: 9091
@ -120,9 +127,10 @@ spec:
tls: tls:
- hosts: - hosts:
- auth.pyrocufflink.blue - auth.pyrocufflink.blue
- auth.pyrocufflink.net
rules: rules:
- host: auth.pyrocufflink.blue - host: auth.pyrocufflink.blue
http: http: &http
paths: paths:
- path: / - path: /
pathType: Prefix pathType: Prefix
@ -131,4 +139,5 @@ spec:
name: authelia name: authelia
port: port:
name: http name: http
- host: auth.pyrocufflink.net
http: *http

View File

@ -5,11 +5,10 @@ access_control:
networks: networks:
- 172.30.0.0/26 - 172.30.0.0/26
- 172.31.1.0/24 - 172.31.1.0/24
- name: cluster
networks:
- 10.149.0.0/16
rules: rules:
- domain: paperless.pyrocufflink.blue
resources:
- '^/api/'
policy: bypass
- domain: paperless.pyrocufflink.blue - domain: paperless.pyrocufflink.blue
policy: two_factor policy: two_factor
subject: subject:
@ -40,6 +39,34 @@ access_control:
networks: networks:
- internal - internal
policy: bypass policy: bypass
- domain: metrics.pyrocufflink.blue
resources:
- '^/insert/.*'
policy: bypass
- domain: metrics.pyrocufflink.blue
networks:
- internal
resources:
- '^/alertmanager([/?].*)?$'
methods:
- GET
- HEAD
- OPTIONS
policy: bypass
- domain: hlcforms.pyrocufflink.blue
resources:
- '^/submit/.*'
policy: bypass
- domain: ara.ansible.pyrocufflink.blue
networks:
- internal
- cluster
resources:
- '^/api/.*'
methods:
- POST
- PATCH
policy: bypass
authentication_backend: authentication_backend:
ldap: ldap:
@ -47,87 +74,123 @@ authentication_backend:
implementation: activedirectory implementation: activedirectory
tls: tls:
minimum_version: TLS1.2 minimum_version: TLS1.2
url: ldaps://pyrocufflink.blue address: ldaps://pyrocufflink.blue
user: CN=svc.authelia,CN=Users,DC=pyrocufflink,DC=blue user: CN=svc.authelia,CN=Users,DC=pyrocufflink,DC=blue
certificates_directory: /run/authelia/certs certificates_directory: /run/authelia/certs
identity_providers: identity_providers:
oidc: oidc:
claims_policies:
default:
id_token:
- groups
- email
- email_verified
- preferred_username
- name
clients: clients:
- id: e20a50c2-55eb-4cb1-96ce-fe71c61c1d89 - client_id: e20a50c2-55eb-4cb1-96ce-fe71c61c1d89
description: Jenkins client_name: Jenkins
secret: >- client_secret: >-
$argon2id$v=19$m=65536,t=3,p=4$qoo6+3ToLbsZOI/BxcppGw$srNBfpIHqpxLh+VfVNNe27A1Ci9dCKLfB8rWXLNkv44 $argon2id$v=19$m=65536,t=3,p=4$qoo6+3ToLbsZOI/BxcppGw$srNBfpIHqpxLh+VfVNNe27A1Ci9dCKLfB8rWXLNkv44
redirect_uris: redirect_uris:
- https://jenkins.pyrocufflink.blue/securityRealm/finishLogin - https://jenkins.pyrocufflink.blue/securityRealm/finishLogin
response_types:
- code
scopes: scopes:
- openid - openid
- groups - groups
- profile - profile
- email - email
- offline_access - offline_access
- address
- phone
authorization_policy: one_factor authorization_policy: one_factor
pre_configured_consent_duration: 8h pre_configured_consent_duration: 8h
- id: kubernetes token_endpoint_auth_method: client_secret_post
description: Kubernetes - client_id: kubernetes
client_name: Kubernetes
public: true public: true
claims_policy: default
redirect_uris: redirect_uris:
- http://localhost:8000 - http://localhost:8000
- http://localhost:18000 - http://localhost:18000
authorization_policy: one_factor authorization_policy: one_factor
pre_configured_consent_duration: 8h pre_configured_consent_duration: 8h
- id: 1b6adbfc-d9e0-4cab-b780-e410639dc420 - client_id: 1b6adbfc-d9e0-4cab-b780-e410639dc420
description: MinIO client_name: MinIO
secret: >- client_secret: >-
$pbkdf2-sha512$310000$TkQ1BwLrr.d8AVGWk2rLhA$z4euAPhkkZdjcxKFD3tZRtNQ/R78beW7epJ.BGFWSwQdAme5TugNj9Ba.aL5TEqrBDmXRW0xiI9EbxSszckG5A $pbkdf2-sha512$310000$TkQ1BwLrr.d8AVGWk2rLhA$z4euAPhkkZdjcxKFD3tZRtNQ/R78beW7epJ.BGFWSwQdAme5TugNj9Ba.aL5TEqrBDmXRW0xiI9EbxSszckG5A
redirect_uris: redirect_uris:
- https://burp.pyrocufflink.blue:9090/oauth_callback - https://burp.pyrocufflink.blue:9090/oauth_callback
- id: step-ca - https://minio.backups.pyrocufflink.blue/oauth_callback
description: step-ca claims_policy: default
- client_id: step-ca
client_name: step-ca
public: true public: true
claims_policy: default
redirect_uris: redirect_uris:
- http://127.0.0.1 - http://127.0.0.1
pre_configured_consent_duration: 8h pre_configured_consent_duration: 8h
- id: argocd - client_id: argocd
description: Argo CD client_name: Argo CD
claims_policy: default
pre_configured_consent_duration: 8h pre_configured_consent_duration: 8h
redirect_uris: redirect_uris:
- https://argocd.pyrocufflink.blue/auth/callback - https://argocd.pyrocufflink.blue/auth/callback
secret: >- client_secret: >-
$pbkdf2-sha512$310000$l/uOezgWjqe3boGLYAnKcg$uqn1FC8Lj2y1NG5Q91PeLfLLUQ.qtlKFLd0AWJ56owLME9mV/Zx8kQ2x7OS/MOoMLmUgKd4zogYKab2HGFr0kw $pbkdf2-sha512$310000$l/uOezgWjqe3boGLYAnKcg$uqn1FC8Lj2y1NG5Q91PeLfLLUQ.qtlKFLd0AWJ56owLME9mV/Zx8kQ2x7OS/MOoMLmUgKd4zogYKab2HGFr0kw
- id: argocd-cli - client_id: argocd-cli
description: argocd CLI client_name: argocd CLI
public: true public: true
claims_policy: default
pre_configured_consent_duration: 8h pre_configured_consent_duration: 8h
audience: audience:
- argocd-cli - argocd-cli
redirect_uris: redirect_uris:
- http://localhost:8085/auth/callback - http://localhost:8085/auth/callback
response_types:
- code
scopes:
- openid
- groups
- profile
- email
- offline_access
- client_id: sshca
client_name: SSHCA
public: true
claims_policy: default
pre_configured_consent_duration: 4h
redirect_uris:
- http://127.0.0.1
scopes: scopes:
- openid - openid
- profile - profile
- email - email
- groups - groups
- offline_access
log: log:
level: trace level: info
notifier: notifier:
smtp: smtp:
disable_require_tls: true disable_require_tls: true
host: mail.pyrocufflink.blue address: 'mail.pyrocufflink.blue:25'
port: 25
sender: auth@pyrocufflink.net sender: auth@pyrocufflink.net
session: session:
domain: pyrocufflink.blue
expiration: 1d expiration: 1d
inactivity: 4h inactivity: 4h
redis: redis:
host: redis host: redis
port: 6379 port: 6379
cookies:
- domain: pyrocufflink.blue
authelia_url: 'https://auth.pyrocufflink.blue'
- domain: pyrocufflink.net
authelia_url: 'https://auth.pyrocufflink.net'
server: server:
buffers: buffers:
@ -135,8 +198,15 @@ server:
storage: storage:
postgres: postgres:
host: default.postgresql address: postgresql.pyrocufflink.blue
database: authelia database: authelia
username: authelia.authelia username: authelia
password: unused
tls: tls:
skip_verify: false skip_verify: false
telemetry:
metrics:
enabled: true
theme: auto

View File

@ -1,25 +1,29 @@
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
namespace: authelia
labels: labels:
- pairs: - pairs:
app.kubernetes.io/instance: authelia app.kubernetes.io/instance: authelia
resources: resources:
- ../dch-root-ca
- secrets.yaml - secrets.yaml
- redis.yaml - redis.yaml
- authelia.yaml - authelia.yaml
- oidc-cluster-admin.yaml - oidc-cluster-admin.yaml
- postgres-cert.yaml
replicas:
- name: authelia
count: 2
configMapGenerator: configMapGenerator:
- name: authelia - name: authelia
namespace: authelia namespace: authelia
files: files:
- configuration.yml - configuration.yml
- name: postgresql-ca
namespace: authelia
files:
- postgresql-ca.crt
patches: patches:
- patch: |- - patch: |-
@ -33,18 +37,25 @@ patches:
spec: spec:
containers: containers:
- name: authelia - name: authelia
imagePullPolicy: IfNotPresent
env: env:
- name: AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE - name: AUTHELIA_STORAGE_POSTGRES_TLS_CERTIFICATE_CHAIN_FILE
value: /run/authelia/secrets/postgresql/password value: /run/authelia/certs/postgresql/tls.crt
- name: AUTHELIA_STORAGE_POSTGRES_TLS_PRIVATE_KEY_FILE
value: /run/authelia/certs/postgresql/tls.key
volumeMounts: volumeMounts:
- mountPath: /run/authelia/certs - mountPath: /run/authelia/certs/dch-root-ca.crt
name: postgresql-ca name: dch-root-ca
- mountPath: /run/authelia/secrets/postgresql subPath: dch-root-ca.crt
name: postgresql-auth - mountPath: /run/authelia/certs/postgresql
name: postgresql-cert
volumes: volumes:
- name: postgresql-auth - name: postgresql-cert
secret: secret:
secretName: authelia.authelia.default.credentials.postgresql.acid.zalan.do secretName: postgres-client-cert
- name: postgresql-ca - name: dch-root-ca
configMap: configMap:
name: postgresql-ca name: dch-root-ca
images:
- name: ghcr.io/authelia/authelia
newTag: 4.39.9

View File

@ -0,0 +1,12 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: postgres-client-cert
spec:
commonName: authelia
privateKey:
algorithm: ECDSA
secretName: postgres-client-cert
issuerRef:
name: postgresql-ca
kind: ClusterIssuer

View File

@ -3,6 +3,7 @@ kind: Kustomization
resources: resources:
- https://github.com/kubernetes/autoscaler/raw/cluster-autoscaler-release-1.26/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml - https://github.com/kubernetes/autoscaler/raw/cluster-autoscaler-release-1.26/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
- secrets.yaml
images: images:
- name: k8s.gcr.io/autoscaling/cluster-autoscaler - name: k8s.gcr.io/autoscaling/cluster-autoscaler
@ -21,6 +22,7 @@ patches:
spec: spec:
containers: containers:
- name: cluster-autoscaler - name: cluster-autoscaler
imagePullPolicy: IfNotPresent
command: command:
- ./cluster-autoscaler - ./cluster-autoscaler
- --v=4 - --v=4

16
autoscaler/secrets.yaml Normal file
View File

@ -0,0 +1,16 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: autoscaler-aws-keys
namespace: kube-system
spec:
encryptedData:
access_key_id: AgA8WLIutrqtizbW/gRNjUaTV9AebXviLX0ffhvRTKVQnPbmjWYUOEyqI6inXmNmxIE342+U0oDtYs878+yHYIxfRAcUi6FRIKPpbUtICzgaudHnjYZaT8gpp20M/ovijkbHTSZMO7snxB72CAa0uzfs+NIY3ky5kDsBDEQKhUix7kQ5Zn75mIBEZhV/W1n5tPQ80k0rykcGt174VPTOtKWV9pIqVJxkw3xZE4vrxB6Cb5S7FfSft5te2vWld8oKE6wbCgEbRVROQ+Q3NfvY8I1jTzZT1eSIHuYM9OmS8NL1S9DOLl/6Pin4jLoBJEaIHOT5abOQLtvQUSuuOvbdbePHaoABBUG+TSXNZnM9GlF+an461ARxHZi51TtjcAHp9063ClTICiEuNT5VoGyfH6Z67MGVtox5DmOo28mgPE1OXALmC3Z3QV/uSIyulTrkV/VDTvp7au21m1nEd54/pzLXUtn78hwv8rnJ9gJGsgq9ovM42Yyo964zN5oBvZkzkIGLPqjAJUEYtXwvOSUprrmyWnJ7bdFZMvx2yGT0S3Hdwt2o6svuPMhXKVI9Ykd122hA14n1/UpimnBq7nAy3EQmCPTAQOh5ufCjqUG3z722aY1KDPDZA+cL8XfrI7JRae+gH0zrCxjKMCyibdz8MHd0ca2n/t42NVbPO0AptY1OKoDK2byUwuAXZl+e9aE302y5Y4ZNiJu+yhaAHZ1gtiDp07eLKA==
secret_access_key: AgAkFztvEEVWpioxcnNJ7b077AzyJ5IMtgKn0nVa+tMzEYWzuWe45G2MuPwajARj5Ji8WH4gwzcBwJOBfuDMmBz7GeodoZJ2tVcbcNg/5dZp5LA9IU3WqUMGIf0lMMnlOaxIxm1Zy+stJM7lbNabA9Nh+NXq4BpcGj+fUevYodhJpLyP7gqKSLZlvsfXVxX8O9XxADUMb1NrAYBx+0J19lh8WkJe2s9oQzpJND6pj3dUlb8UbBdg6uD4CSlORcSW1WdqQz9WW/clt0eBO1hlgVC6me7GlWtAqm88+1+sBlmT7SrCzbP0Ky7w2xz9L6Y2I9k65c2yCwkPrfh6CiIXltjPZEtvL+gzIIvXNIO1XUX4FlcSu+AartVPyDkAuA0TsMEuaORo0C9HnxSYm4fHRaDe2HZWwXCLXXyW1xZxfy0le1pr9zUNcx5HFjR7XJ6E3seirIyk8B9CnqDY/Ff29PQzDjv2k50UiSXHLIpwbZ5G2nqYzkOG2MRhjggiYKh7VPpKTwQUebVyFsdiLaAFcWr8BrLwXXcbOeEpHRnsZlCCqXM1uN4H3Am0RuRc12V2pYWHP/q53sSfYYBDsXFHOXr6e3iZ/c95GI/ndjaBqk1EtV7go4wn5sZaZvDmQktYalNKYk4EZLzAsgj7PdOeS5SDa2ZnQud4Om7a2MRoayntg8pyCeLfvV6G5CwuUh/kFZVn+2v2OTabC+6HMde4Yq1MMrFD+qOKGywHMG8HvZieHCzi4ZnnT3Wt
template:
metadata:
creationTimestamp: null
name: autoscaler-aws-keys
namespace: kube-system

10
calico/kustomization.yaml Normal file
View File

@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
labels:
- pairs:
app.kubernetes.io/instance: calico
resources:
- https://raw.githubusercontent.com/projectcalico/calico/v3.30.2/manifests/operator-crds.yaml
- https://raw.githubusercontent.com/projectcalico/calico/v3.30.2/manifests/tigera-operator.yaml

View File

@ -1,133 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: cert-exporter
namespace: cert-manager
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cert-exporter
namespace: cert-manager
data:
config.yml: |
git_repo: gitea@git.pyrocufflink.blue:dustin/certs.git
certs:
- name: pyrocufflink-cert
namespace: default
key: certificates/_.pyrocufflink.net.key
cert: certificates/_.pyrocufflink.net.crt
bundle: certificates/_.pyrocufflink.net.pem
- name: dustinhatchname-cert
namespace: default
key: acme.sh/dustin.hatch.name/dustin.hatch.name.key
cert: acme.sh/dustin.hatch.name/fullchain.cer
- name: hatchchat-cert
namespace: default
key: certificates/hatch.chat.key
cert: certificates/hatch.chat.crt
bundle: certificates/hatch.chat.pem
- name: tabitha-cert
namespace: default
key: certificates/tabitha.biz.key
cert: certificates/tabitha.biz.crt
bundle: certificates/tabitha.biz.pem
- name: dcow-cert
namespace: default
key: certificates/darkchestofwonders.us.key
cert: certificates/darkchestofwonders.us.crt
bundle: certificates/darkchestofwonders.us.pem
- name: chmod777-cert
namespace: default
key: certificates/chmod777.sh.key
cert: certificates/chmod777.sh.crt
bundle: certificates/chmod777.sh.pem
- name: dustinandtabitha-cert
namespace: default
key: certificates/dustinandtabitha.com.key
cert: certificates/dustinandtabitha.com.crt
bundle: certificates/dustinandtabitha.com.pem
- name: hlc-cert
namespace: default
key: certificates/hatchlearningcenter.org.key
cert: certificates/hatchlearningcenter.org.crt
bundle: certificates/hatchlearningcenter.org.pem
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: cert-exporter
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
resourceNames:
- pyrocufflink-cert
- dustinhatchname-cert
- hatchchat-cert
- tabitha-cert
- dcow-cert
- chmod777-cert
- dustinandtabitha-cert
- hlc-cert
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cert-exporter
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: cert-exporter
subjects:
- kind: ServiceAccount
name: cert-exporter
namespace: cert-manager
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: cert-exporter
namespace: cert-manager
spec:
timeZone: America/Chicago
schedule: '27 9,20 * * *'
jobTemplate: &jobtemplate
spec:
template:
spec:
containers:
- image: git.pyrocufflink.net/containerimages/cert-exporter
name: cert-exporter
volumeMounts:
- mountPath: /etc/cert-exporter/config.yml
name: config
subPath: config.yml
readOnly: true
- mountPath: /home/cert-exporter/.ssh/id_ed25519
name: sshkeys
subPath: cert-exporter.pem
readOnly: true
- mountPath: /etc/ssh/ssh_known_hosts
name: sshkeys
subPath: ssh_known_hosts
readOnly: true
securityContext:
fsGroup: 1000
serviceAccount: cert-exporter
volumes:
- name: config
configMap:
name: cert-exporter
- name: sshkeys
secret:
secretName: cert-exporter-sshkey
defaultMode: 00440
restartPolicy: Never

File diff suppressed because it is too large Load Diff

View File

@ -16,141 +16,3 @@ spec:
privateKey: privateKey:
algorithm: ECDSA algorithm: ECDSA
rotationPolicy: Always rotationPolicy: Always
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: dustinhatchname-cert
spec:
secretName: dustinhatchname-cert
dnsNames:
- dustin.hatch.name
- '*.dustin.hatch.name'
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: zerossl
privateKey:
algorithm: ECDSA
rotationPolicy: Always
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: hatchchat-cert
spec:
secretName: hatchchat-cert
dnsNames:
- hatch.chat
- '*.hatch.chat'
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: zerossl
privateKey:
algorithm: ECDSA
rotationPolicy: Always
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: tabitha-cert
spec:
secretName: tabitha-cert
dnsNames:
- tabitha.biz
- '*.tabitha.biz'
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: zerossl
privateKey:
algorithm: ECDSA
rotationPolicy: Always
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: dcow-cert
spec:
secretName: dcow-cert
dnsNames:
- darkchestofwonders.us
- '*.darkchestofwonders.us'
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: zerossl
privateKey:
algorithm: ECDSA
rotationPolicy: Always
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: chmod777-cert
spec:
secretName: chmod777-cert
dnsNames:
- chmod777.sh
- '*.chmod777.sh'
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: zerossl
privateKey:
algorithm: ECDSA
rotationPolicy: Always
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: dustinandtabitha-cert
spec:
secretName: dustinandtabitha-cert
dnsNames:
- dustinandtabitha.com
- '*.dustinandtabitha.com'
- dustinandtabitha.xyz
- '*.dustinandtabitha.xyz'
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: zerossl
privateKey:
algorithm: ECDSA
rotationPolicy: Always
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: hlc-cert
spec:
secretName: hlc-cert
dnsNames:
- hatchlearningcenter.org
- '*.hatchlearningcenter.org'
- hatchlearningcenter.com
- '*.hatchlearningcenter.com'
- hlckc.org
- '*.hlckc.org'
- hlckc.com
- '*.hlckc.com'
- hlcks.org
- '*.hlcks.org'
- hlcks.com
- '*.hlcks.com'
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: zerossl
privateKey:
algorithm: ECDSA
rotationPolicy: Always

View File

@ -0,0 +1,29 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: dch-ca
spec:
acme:
server: https://ca.pyrocufflink.blue:32599/acme/acme/directory
email: cert-manager@pyrocufflink.net
privateKeySecretRef:
name: dch-ca-acme
caBundle:
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ4RENDQVdxZ0F3SUJBZ0lVYkh6MnRzc2EwOXpzSGsrRWRHRDNRS3ByTUtRd0NnWUlLb1pJemowRUF3UXcKUURFTE1Ba0dBMVVFQmhNQ1ZWTXhHREFXQmdOVkJBb01EMFIxYzNScGJpQkRMaUJJWVhSamFERVhNQlVHQTFVRQpBd3dPUkVOSUlGSnZiM1FnUTBFZ1VqSXdIaGNOTWpNd09USTBNakExTXpBNVdoY05ORE13T1RFNU1qQTFNekE1CldqQkFNUXN3Q1FZRFZRUUdFd0pWVXpFWU1CWUdBMVVFQ2d3UFJIVnpkR2x1SUVNdUlFaGhkR05vTVJjd0ZRWUQKVlFRRERBNUVRMGdnVW05dmRDQkRRU0JTTWpCWk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQkUyRApOSkhSY2p1QTE5Wm9wckJLYXhJZlV4QWJ6NkxpZ003ZGd0TzYraXNhTWx4UkFWSm1zSVRBRElFLzIyUnJVRGdECk9ma3QyaVpUVWpNcnozQXhYaFdqUWpCQU1CMEdBMVVkRGdRV0JCVE0rZDhrYjFrb0dtS1J0SnM0Z045ellhKzYKb1RBU0JnTlZIUk1CQWY4RUNEQUdBUUgvQWdFQk1Bc0dBMVVkRHdRRUF3SUJCakFLQmdncWhrak9QUVFEQkFOSQpBREJGQWlFQTJLYThtTWlBRkxtckZXdDBkQW1sMjQ3cmUyK2k0VVBoeUhjT0JmTksrZ29DSUh2K3ZFdzdDSFpRCmlySWE2OTduZmU0S2lYSU13SGxBTVMxKzFRWm9oRkRDCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
solvers:
- dns01:
cnameStrategy: Follow
rfc2136:
nameserver: 172.30.0.1
tsigSecretSecretRef:
name: pyrocufflink-tsig
key: cert-manager.tsig.key
tsigKeyName: cert-manager
tsigAlgorithm: HMACSHA512
selector:
dnsNames:
- rabbitmq.pyrocufflink.blue
- http01:
ingress:
ingressClassName: nginx

27
cert-manager/jenkins.yaml Normal file
View File

@ -0,0 +1,27 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
resourceNames:
- pyrocufflink-cert
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: default
namespace: jenkins-jobs

View File

@ -2,19 +2,14 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
resources: resources:
- cert-manager.yaml - https://github.com/cert-manager/cert-manager/releases/download/v1.16.4/cert-manager.yaml
- cluster-issuer.yaml - cluster-issuer.yaml
- certificates.yaml - certificates.yaml
- cert-exporter.yaml - dch-ca-issuer.yaml
- secrets.yaml
- jenkins.yaml
secretGenerator: secretGenerator:
- name: cert-manager-tsig
namespace: cert-manager
files:
- cert-manager.key
options:
disableNameSuffixHash: true
- name: zerossl-eab - name: zerossl-eab
namespace: cert-manager namespace: cert-manager
envs: envs:
@ -22,22 +17,34 @@ secretGenerator:
options: options:
disableNameSuffixHash: true disableNameSuffixHash: true
- name: cert-exporter-sshkey
namespace: cert-manager
files:
- cert-exporter.pem
- ssh_known_hosts
- name: acme-dns
namespace: cert-manager
files:
- acme-dns.json
options:
disableNameSuffixHash: true
- name: cloudflare - name: cloudflare
namespace: cert-manager namespace: cert-manager
files: files:
- cloudflare.api-token - cloudflare.api-token
options: options:
disableNameSuffixHash: true disableNameSuffixHash: true
patches:
- patch: |
apiVersion: apps/v1
kind: Deployment
metadata:
name: cert-manager
namespace: cert-manager
spec:
template:
spec:
dnsConfig:
nameservers:
- 172.30.0.1
dnsPolicy: None
- patch: |
- op: add
path: /spec/template/spec/containers/0/args/-
value: >-
--dns01-recursive-nameservers-only
target:
group: apps
version: v1
kind: Deployment
name: cert-manager

13
cert-manager/secrets.yaml Normal file
View File

@ -0,0 +1,13 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: pyrocufflink-tsig
namespace: cert-manager
spec:
encryptedData:
cert-manager.tsig.key: AgAf1dVezJ0ytOdGI5rzCJ35rAVpY114pQJgIzqAKsKkRVE6kwWXjoFj94ZgDsjpOedAp1zdNB1UQnu0n10ayuz/NUYb74wkXcu0RRy6Ve06SJjI01f7lHP2/a4cnW+0et/Xzin0RQ/3hHmZUk5aCwV/FCLs0D5LdFixHf+sbMCzhyIYrQ64x0YH9YqBTRgXkEx94+PUuxi9ZyLuKiepd/K4UF+L5rF2zWt9DVKOmdbilzd5RqdQSgEyoOOpmcbDKHm1s17KHWSJb44rvxj7vg2fmXXwEvEW5SiQdrhmywOcqqhXEbE1ZEvBrVt3GgrjZHeTyL0Gx4jugiqSR/WulY7ak4+ZkDF80OS5RzciYeVMDdNxst48Xdkc2F7E93GGWCeIN5gig0oCFcB18BRF3aO4AB+fqh0IWBSiBCGinbjvX684TF9BGPuKMj01ORW3fFnRfbeE4gYTrdBKFi1ltG6VxJ6X9i5ztLIQBcH48btf7uMjQsC79GPq35CCWBprqnNBvi81lJtGVaVqY6hNIvyQIO+fEReMk/Mp0N+KxWlWVY/vK+ck2KWkgXaui3xkM4jbB6RiXWZXrUW4y+XyDs+sTziwYRRz03MU9NC58do9MBnOeM+fJqioMyQq81/mXKtcxIsvJadJ7WsYQKdqa/gVE5D/ybJ2qrtbEQqgCXnyowIIIOVvvWilhzh/zjQgtRiLHlsbLmvRX5aZm1Z048CMDFPh8CxcHlVwz7FUviJzbNoqENh1PE6HhKwFqpGxtjjR6X3LEi8iLvLNg05EUzLNJD1+SCi0imhQPGesJZtr/h1xqI9utB4NjA==
template:
metadata:
name: pyrocufflink-tsig
namespace: cert-manager

View File

@ -0,0 +1,10 @@
LoadPlugin df
<Plugin df>
ReportByDevice true
FSType autofs
FSType overlay
FSType efivarfs
IgnoreSelected true
</Plugin>

View File

@ -0,0 +1,8 @@
LoadPlugin logfile
<Plugin logfile>
LogLevel info
File stderr
Timestamp false
PrintSeverity true
</Plugin>

View File

@ -0,0 +1,9 @@
LoadPlugin chrony
LoadPlugin cpufreq
LoadPlugin disk
LoadPlugin entropy
LoadPlugin processes
LoadPlugin swap
LoadPlugin tcpconns
LoadPlugin thermal
LoadPlugin uptime

View File

@ -0,0 +1,5 @@
LoadPlugin write_prometheus
<Plugin write_prometheus>
Port 9103
</Plugin>

74
collectd/collectd.yaml Normal file
View File

@ -0,0 +1,74 @@
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: collectd
labels:
app.kubernetes.io/name: collectd
app.kubernetes.io/component: collectd
spec:
selector:
matchLabels:
app.kubernetes.io/name: collectd
app.kubernetes.io/component: collectd
template:
metadata:
labels:
app.kubernetes.io/name: collectd
app.kubernetes.io/component: collectd
spec:
containers:
- name: collectd
image: git.pyrocufflink.net/containerimages/collectd
ports:
- containerPort: 9103
name: http
readinessProbe: &probe
httpGet:
port: http
path: /metrics
periodSeconds: 60
startupProbe:
<<: *probe
periodSeconds: 1
successThreshold: 1
failureThreshold: 30
timeoutSeconds: 1
securityContext:
capabilities:
add:
- DAC_READ_SEARCH
drop:
- ALL
seLinuxOptions:
type: spc_t
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /etc/collectd.d
name: config
readOnly: true
- mountPath: /host
name: host
- mountPath: /run
name: host
subPath: run
- mountPath: /tmp
name: tmp
hostNetwork: true
hostPID: true
hostIPC: true
tolerations:
- effect: NoExecute
operator: Exists
- effect: NoSchedule
operator: Exists
volumes:
- name: config
configMap:
name: collectd
- name: host
hostPath:
path: /
- name: tmp
emptyDir:
medium: Memory

View File

@ -0,0 +1,34 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: collectd
labels:
- pairs:
app.kubernetes.io/instance: collectd
app.kubernetes.io/part-of: collectd
includeSelectors: false
resources:
- namespace.yaml
- collectd.yaml
configMapGenerator:
- name: collectd
files:
- collectd.d/df.conf
- collectd.d/log.conf
- collectd.d/plugins.conf
- collectd.d/prometheus.conf
patches:
- patch: |-
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: collectd
spec:
template:
spec:
nodeSelector:
du5t1n.me/collectd: 'true'

6
collectd/namespace.yaml Normal file
View File

@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: collectd
labels:
app.kubernetes.io/name: collectd

View File

@ -5,3 +5,5 @@ configMapGenerator:
- name: dch-root-ca - name: dch-root-ca
files: files:
- dch-root-ca.crt - dch-root-ca.crt
options:
disableNameSuffixHash: true

View File

@ -0,0 +1,121 @@
apiVersion: batch/v1
kind: Job
metadata:
generateName: host-provision-
labels: &labels
app.kubernetes.io/name: host-provisioner
app.kubernetes.io/component: host-provisioner
spec:
backoffLimit: 0
template:
metadata:
labels: *labels
spec:
restartPolicy: Never
initContainers:
- name: ssh-agent
image: &image git.pyrocufflink.net/infra/host-provisioner
imagePullPolicy: Always
command:
- tini
- ssh-agent
- --
- -D
- -a
- /run/ssh/agent.sock
restartPolicy: Always
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /run/ssh
name: tmp
subPath: run/ssh
- name: ssh-add
image: *image
command:
- ssh-add
- -t
- 30m
- /run/secrets/ssh/host-provisioner.key
env:
- name: SSH_AUTH_SOCK
value: /run/ssh/agent.sock
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /run/ssh
name: tmp
subPath: run/ssh
- mountPath: /run/secrets/ssh
name: provisioner-key
readOnly: true
containers:
- name: host-provisioner
image: *image
env:
- name: SSH_AUTH_SOCK
value: /run/ssh/agent.sock
- name: AMQP_HOST
value: rabbitmq.pyrocufflink.blue
- name: AMQP_PORT
value: '5671'
- name: AMQP_CA_CERT
value: /run/dch-ca/dch-root-ca.crt
- name: AMQP_CLIENT_CERT
value: /run/secrets/host-provisioner/rabbitmq/tls.crt
- name: AMQP_CLIENT_KEY
value: /run/secrets/host-provisioner/rabbitmq/tls.key
- name: AMQP_EXTERNAL_CREDENTIALS
value: '1'
- name: PYROCUFFLINK_EXCLUDE_TEST
value: 'false'
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /etc/ssh/ssh_known_hosts
name: ssh-known-hosts
subPath: ssh_known_hosts
readOnly: true
- mountPath: /home/jenkins
name: workspace
- mountPath: /run/dch-ca
name: dch-root-ca
readOnly: true
- mountPath: /run/ssh
name: tmp
subPath: run/ssh
- mountPath: /run/secrets/host-provisioner/rabbitmq
name: rabbitmq-cert
readOnly: true
- mountPath: /tmp
name: tmp
subPath: tmp
- mountPath: /var/tmp
name: tmp
subPath: tmp
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
serviceAccountName: host-provisioner
volumes:
- name: dch-root-ca
configMap:
name: dch-root-ca
- name: provisioner-key
secret:
secretName: provisioner-ssh-key
defaultMode: 0440
- name: ssh-known-hosts
configMap:
name: ssh-known-hosts
- name: rabbitmq-cert
secret:
secretName: rabbitmq-cert
defaultMode: 0440
- name: tmp
emptyDir:
medium: Memory
- name: workspace
emptyDir: {}

View File

@ -0,0 +1,14 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: rabbitmq
spec:
secretName: rabbitmq-cert
commonName: dch-webhooks
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: rabbitmq-ca
privateKey:
algorithm: ECDSA
rotationPolicy: Always

View File

@ -7,3 +7,10 @@ STEP_CA_URL=https://ca.pyrocufflink.blue:32599
STEP_ROOT=/run/dch-root-ca.crt STEP_ROOT=/run/dch-root-ca.crt
STEP_PROVISIONER=host-bootstrap STEP_PROVISIONER=host-bootstrap
STEP_PROVISIONER_PASSWORD_FILE=/run/secrets/du5t1n.me/step-ca/provisioner.password STEP_PROVISIONER_PASSWORD_FILE=/run/secrets/du5t1n.me/step-ca/provisioner.password
AMQP_HOST=rabbitmq.pyrocufflink.blue
AMQP_PORT=5671
AMQP_EXTERNAL_CREDENTIALS=1
AMQP_CA_CERT=/run/dch-root-ca.crt
AMQP_CLIENT_CERT=/run/secrets/du5t1n.me/rabbitmq/tls.crt
AMQP_CLIENT_KEY=/run/secrets/du5t1n.me/rabbitmq/tls.key

View File

@ -1,4 +1,14 @@
apiVersion: v1 apiVersion: v1
kind: ServiceAccount
metadata:
name: dch-webhooks
labels:
app.kubernetes.io/name: dch-webhooks
app.kubernetes.io/component: dch-webhooks
app.kubernetes.io/part-of: dch-webhooks
---
apiVersion: v1
kind: Service kind: Service
metadata: metadata:
labels: labels:
@ -48,6 +58,8 @@ spec:
value: 0.0.0.0 value: 0.0.0.0
- name: UVICORN_LOG_LEVEL - name: UVICORN_LOG_LEVEL
value: debug value: debug
- name: ANSIBLE_JOB_YAML
value: /etc/dch-webhooks/ansible-job.yaml
envFrom: envFrom:
- configMapRef: - configMapRef:
name: dch-webhooks name: dch-webhooks
@ -76,23 +88,44 @@ spec:
name: firefly-token name: firefly-token
- mountPath: /run/secrets/du5t1n.me/paperless - mountPath: /run/secrets/du5t1n.me/paperless
name: paperless-token name: paperless-token
- mountPath: /run/secrets/du5t1n.me/rabbitmq
name: rabbitmq-cert
readOnly: true
- mountPath: /run/secrets/du5t1n.me/step-ca
name: step-ca-password
- mountPath: /tmp - mountPath: /tmp
name: tmp name: tmp
subPath: tmp subPath: tmp
- mountPath: /etc/dch-webhooks
name: host-provisioner
readOnly: true
securityContext: securityContext:
runAsNonRoot: true runAsNonRoot: true
serviceAccountName: dch-webhooks
volumes: volumes:
- name: firefly-token - name: firefly-token
secret: secret:
secretName: firefly-token secretName: firefly-token
optional: true optional: true
- name: host-provisioner
configMap:
name: host-provisioner
optional: true
- name: paperless-token - name: paperless-token
secret: secret:
secretName: paperless-token secretName: paperless-token
optional: true optional: true
- name: rabbitmq-cert
secret:
secretName: rabbitmq-cert
optional: true
- name: root-ca - name: root-ca
configMap: configMap:
name: dch-root-ca name: dch-root-ca
- name: step-ca-password
secret:
secretName: step-ca-password
optional: true
- name: tmp - name: tmp
emptyDir: emptyDir:
medium: Memory medium: Memory

28
dch-webhooks/jenkins.yaml Normal file
View File

@ -0,0 +1,28 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins.dch-webhooks
rules:
- apiGroups:
- apps
resources:
- deployments
resourceNames:
- dch-webhooks
verbs:
- get
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins.dch-webhooks
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins.dch-webhooks
subjects:
- kind: ServiceAccount
name: default
namespace: jenkins-jobs

View File

@ -1,13 +1,39 @@
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
labels:
- pairs:
app.kubernetes.io/instance: dch-webhooks
includeSelectors: true
includeTemplates: true
- pairs:
app.kubernetes.io/part-of: dch-webhooks
resources: resources:
- ../dch-root-ca - ../dch-root-ca
- dch-webhooks.yaml - dch-webhooks.yaml
- certificate.yaml
- ingress.yaml - ingress.yaml
- secrets.yaml
configMapGenerator: configMapGenerator:
- name: dch-webhooks - name: dch-webhooks
envs: envs:
- dch-webhooks.env - dch-webhooks.env
- name: host-provisioner
files:
- ansible-job.yaml
options:
disableNameSuffixHash: true
secretGenerator:
- name: firefly-token
files:
- firefly.token
- name: paperless-token
files:
- paperless.token
- name: step-ca-password
files:
- provisioner.password

View File

@ -1,28 +0,0 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: firefly-token
namespace: default
spec:
encryptedData:
firefly.token: AgB8sD5GEwGMiCUQEioisw+ni5DqJM3L7AEwMnrdlrK7gq2TL/Htqo2TzuUIMxovf9KPkUWD4Y7KpT52z88yysbHlcEQkjB6djJYYecMyNVvPVYBEbKp+zLlJGqPTVoCrcvxaNAOTgOEnUx0zhWy90qWmmWQ4JPEfu1pm7++ZWJhp9c8p2HYsiQ81WV23IIp3Ua+7FK45+QxL1D1W1OXjqYs8BhXDgMS3bc5YGNTEx+e+fKN/i+KlKuO0h6ONt9vp8+DS3sQuiW+pkB+1Ra4bZ3RWZoVyqaoPdQZ95DCOTT6r8dDZObS6rxO3J1Bmppm1xB6zpN5HVFJnE0NpX0ljLSSk59BDZ3LLVawm9QAgwLKVLuyJ9hdlUDJD+EH2gj8ioxiiUAWHqThP3xBjoKD7nZWgyGM0zdyZuX+mADAflyAwcOydRwIXA6s5Tjw5RM0RWQ5JrOJGDAO41LOHoRu6qlFMmwc4novu4tzvlRvakqND4BxCEhDk6v4P1pDQh2xP2fvD3HOU5rqlq3z1X5lPnKHkRJUi2v0pryGBhoLrt8htCYA+w0LjMTx3c5dVC7Fz41U/7vVWhoQcPLNGx9I4Npb9z1qs8ozQCJUCdbPOaEnoKJtMVr2ByoR3WLr4hMT4b1Z2gFfU1rwhz3TO2xTCbY956GXaj1QACk67uHxvzLFaW0Td6vNHJGxQcgbtPvdtzS6yuNlF6W6Y3SlmADjvq5YeIF8n6UviIqqihYf4+os1r3ea14T7Jsi5VCNO1GyXLAke9oQruXe2sXAkTg6xbu+bgUqxDUqjkF677fVRlBTWcpf0gFsqGpHSkVK782I4Z+OUQMceE3+yJzkOD3DzZkGihQUuj82pctY7Ik2nDfc90JE4WMF9gmK1MxnS67yqcvHjKm7yuGNoP8JvdClmQcipJ3LsVdXm4s4dpmWCHDoqkMbN8+KDnh2TjTDwndcsCkCe5cWrKZfwMn9zQyPHH+/BWT77KwNviO6MjLDUzP1CWWAXmizxZozzIYSq67IUggAifv0n2oaBMyN7CsRZaL5KKMdLBhmE4EcEZvxDnRaxII2oWw5B2uyfyD2YWy35K0WRxHQH+TUmZEvPG3e2EWQcj8NR6L6J2wB4h4y2EJXRhrdbgZBppMQ0j22QZsw+0Yiol3uR9oLYlVXXgpkxuDTPUkm9k3GPItJmE75RmInI6xBKUMkueZQBYfSmoYLhsfwliMQ0rPnuY7kEIDJTS5NPrJqdkSZY5chkl9pSDeearJQLaFyB6PXZtBWz+6CqqKZFTO/YOPgU/9zqeUEWoyPUZ1FAVJ3aMrirscHz37jqTgQbn6hMW+WCw2WiApoMG9D+xU5ZfQRIph+Y3S1QjGdfxH7oE7XIuLdy6bQ7Cw93MZVn9kaIvLzcZTHtptOxy0XpygfalC/SDcubBpGCCKDw2I5xpkEC165ZKKM/NN3mxXZKeSY+8nePWl+pZeU8etiulGtQ/ZIqOmGaU7W4T5gJCij1bpGKS28lNhv25lUxMFBvyheLn6qUIMIRdCsvr6OdF+YOQQLLzwDquDD9ankHGzKMI73OWDCFrhXl85QqPg62bVCdghEMlohY4Wniy5k2CRLM0pQm9OZsp+RlPvv/Ea9JxyjQGtv4EcCXG2nv5ewWysv8mIYd8qWH/ZSh2o44pixC0levmrOXMb6cC5T3TC9OI6w1DglF84k3+bVGn+wNAHbo5ALxAhdGmB/GTdSRS1x368o4k2E0MThsezymlfjo8K8wyFWMpHpat/eF7WQy2ibl/lt6sCk8iBFEb4LPVbb68w4gZhPHHqcfZ//9+0rC28eagpYfx6LQi8gDUC/Uw06iPygJBOKABdppLNHqNa6zzOET2yECRlAtuxCmO9WYEpi0cOzg8fvdSzP57f47MJu3vnztFo1AIx5YU0Ohlv9KtjNxTaXziAJY47Y8o9jEnT7ajb81pwLf1/iMHT73TZtu8tVWKKZ7VReEQUzeKfERoboZO/P8TrVOvkK3ZLw5+tA
template:
metadata:
name: firefly-token
namespace: default
type: Opaque
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: paperless-token
namespace: default
spec:
encryptedData:
paperless.token: AgBV2pcAAh+4bbMiNbKqRgFCNOpuZ19H6+YDSbM56pqyV3NRUZTiaRdPReG9T0WxRcYzjHluX7fIrr1kq8uIaCBDhnckdEjITwYqYRDtl6GDXhEXgfXt2HIKkBpBX+rK6j/qwlXpqwtx2oIq30G20WSll7wPsexQ/c0ZvquZysQ1/r7NvynbJB1/1lNk6wnEkRnByCWJI//0nQjYAeUeliftqU2e+PkpETGRyrUlaPlRt4NBaFbJDgZSBh1qlHqE4t0Lf23VdE0VVeFDaDR9EjVO4DPiwC7BEAfDi65+DM6iXUygAfyYL9KsCQGbUdxdb7SAp/ROCVUuu+dLGh1upk42J3XGa1rufN2XtXLCRL8MQ1j4JeV7Jm3yewNt4WYP6tD8UYKBxhRUK5pYU12jBR8yWZ1BBWNvWRN1w++pklMF72N95R61qJQhlftbq8F4yHj4Vh/9n+usJ1zw8LaZg179ZucIV9byA3NrDnbvDWLCvs/sVycrXbcnPec6+oMrgJL6lp96ofjBxqWDCDp/SUBUkDC34jiiaxjzrY5q9hUyf5gdqbzKN5Jda2lHvj6UgJj6Qo8AdQmMF6MNH4X2A1Ni2mR/WTwNzXDGfHibLeaTuBSyvALFoIbuuR78Wkjz76ZC6SQT8HwwCeylPskd7KPJURpJfXfdB/UwyV02LveZpsASgQo/m22znCZVwVhrOlC8SvNht4WO5HgHBf+21cSHfwZ03NM/81fedfxyySvMoMjpGy+89hwfnA==
template:
metadata:
name: paperless-token
namespace: default
type: Opaque

2
democratic-csi/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
synology.password
synology-iscsi-chap.yaml

View File

@ -0,0 +1,385 @@
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: csi-synology-democratic-csi-node
namespace: democratic-csi
labels:
app.kubernetes.io/name: democratic-csi
app.kubernetes.io/csi-role: node
app.kubernetes.io/component: node-linux
spec:
selector:
matchLabels:
app.kubernetes.io/name: democratic-csi
app.kubernetes.io/csi-role: node
app.kubernetes.io/component: node-linux
template:
metadata:
labels:
app.kubernetes.io/name: democratic-csi
app.kubernetes.io/csi-role: node
app.kubernetes.io/component: node-linux
spec:
serviceAccount: csi-synology-democratic-csi-node-sa
priorityClassName: system-node-critical
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
hostAliases: []
hostIPC: true
hostPID: false
containers:
- name: csi-driver
image: docker.io/democraticcsi/democratic-csi:latest
args:
- --csi-version=1.5.0
- --csi-name=org.democratic-csi.iscsi-synology
- --driver-config-file=/config/driver-config-file.yaml
- --log-level=info
- --csi-mode=node
- --server-socket=/csi-data/csi.sock.internal
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- SYS_ADMIN
privileged: true
env:
- name: CSI_NODE_ID
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
terminationMessagePath: /tmp/termination-log
terminationMessagePolicy: File
livenessProbe:
failureThreshold: 3
exec:
command:
- bin/liveness-probe
- --csi-version=1.5.0
- --csi-address=/csi-data/csi.sock.internal
initialDelaySeconds: 10
timeoutSeconds: 15
periodSeconds: 60
volumeMounts:
- name: socket-dir
mountPath: /csi-data
- name: kubelet-dir
mountPath: /var/lib/kubelet
mountPropagation: Bidirectional
- name: iscsi-dir
mountPath: /etc/iscsi
mountPropagation: Bidirectional
- name: iscsi-info
mountPath: /var/lib/iscsi
mountPropagation: Bidirectional
- name: modules-dir
mountPath: /lib/modules
readOnly: true
- name: localtime
mountPath: /etc/localtime
readOnly: true
- name: udev-data
mountPath: /run/udev
- name: host-dir
mountPath: /host
mountPropagation: Bidirectional
- mountPath: /sys
name: sys-dir
- name: dev-dir
mountPath: /dev
- name: config
mountPath: /config
- name: csi-proxy
image: docker.io/democraticcsi/csi-grpc-proxy:v0.5.6
env:
- name: BIND_TO
value: unix:///csi-data/csi.sock
- name: PROXY_TO
value: unix:///csi-data/csi.sock.internal
volumeMounts:
- mountPath: /csi-data
name: socket-dir
- name: driver-registrar
image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.9.0
args:
- --v=5
- --csi-address=/csi-data/csi.sock
- --kubelet-registration-path=/var/lib/kubelet/plugins/org.democratic-csi.iscsi-synology/csi.sock
env:
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
livenessProbe:
exec:
command:
- /csi-node-driver-registrar
- --kubelet-registration-path=/var/lib/kubelet/plugins/org.democratic-csi.iscsi-synology/csi.sock
- --mode=kubelet-registration-probe
volumeMounts:
- mountPath: /csi-data
name: socket-dir
- name: registration-dir
mountPath: /registration
- name: kubelet-dir
mountPath: /var/lib/kubelet
- name: cleanup
image: docker.io/busybox:1.37.0
command:
- /bin/sh
args:
- -c
- |-
sleep infinity &
trap 'kill !$' INT TERM
wait
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- rm -rf /plugins/org.democratic-csi.iscsi-synology /registration/org.democratic-csi.iscsi-synology-reg.sock
volumeMounts:
- name: plugins-dir
mountPath: /plugins
- name: registration-dir
mountPath: /registration
volumes:
- name: socket-dir
hostPath:
path: /var/lib/kubelet/plugins/org.democratic-csi.iscsi-synology
type: DirectoryOrCreate
- name: plugins-dir
hostPath:
path: /var/lib/kubelet/plugins
type: Directory
- name: registration-dir
hostPath:
path: /var/lib/kubelet/plugins_registry
type: Directory
- name: kubelet-dir
hostPath:
path: /var/lib/kubelet
type: Directory
- name: iscsi-dir
hostPath:
path: /etc/iscsi
type: Directory
- name: iscsi-info
hostPath:
path: /var/lib/iscsi
- name: dev-dir
hostPath:
path: /dev
type: Directory
- name: modules-dir
hostPath:
path: /lib/modules
- name: localtime
hostPath:
path: /etc/localtime
- name: udev-data
hostPath:
path: /run/udev
- name: sys-dir
hostPath:
path: /sys
type: Directory
- name: host-dir
hostPath:
path: /
type: Directory
- name: config
secret:
secretName: csi-synology-democratic-csi-driver-config
nodeSelector:
kubernetes.io/os: linux
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: csi-synology-democratic-csi-controller
namespace: democratic-csi
labels:
app.kubernetes.io/name: democratic-csi
app.kubernetes.io/csi-role: controller
app.kubernetes.io/component: controller-linux
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: democratic-csi
app.kubernetes.io/csi-role: controller
app.kubernetes.io/component: controller-linux
template:
metadata:
labels:
app.kubernetes.io/name: democratic-csi
app.kubernetes.io/csi-role: controller
app.kubernetes.io/component: controller-linux
spec:
serviceAccount: csi-synology-democratic-csi-controller-sa
priorityClassName: system-cluster-critical
hostNetwork: false
dnsPolicy: ClusterFirst
hostAliases: []
hostIPC: false
containers:
- name: external-attacher
image: registry.k8s.io/sig-storage/csi-attacher:v4.4.0
args:
- --v=5
- --leader-election
- --leader-election-namespace=democratic-csi
- --timeout=90s
- --worker-threads=10
- --csi-address=/csi-data/csi.sock
volumeMounts:
- mountPath: /csi-data
name: socket-dir
- name: external-provisioner
image: registry.k8s.io/sig-storage/csi-provisioner:v3.6.0
args:
- --v=5
- --leader-election
- --leader-election-namespace=democratic-csi
- --timeout=90s
- --worker-threads=10
- --extra-create-metadata
- --csi-address=/csi-data/csi.sock
volumeMounts:
- mountPath: /csi-data
name: socket-dir
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: external-resizer
image: "registry.k8s.io/sig-storage/csi-resizer:v1.9.0"
args:
- --v=5
- --leader-election
- --leader-election-namespace=democratic-csi
- --timeout=90s
- --workers=10
- --csi-address=/csi-data/csi.sock
volumeMounts:
- mountPath: /csi-data
name: socket-dir
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
# https://github.com/kubernetes-csi/external-snapshotter
# beware upgrading version:
# - https://github.com/rook/rook/issues/4178
# - https://github.com/kubernetes-csi/external-snapshotter/issues/147#issuecomment-513664310
- name: external-snapshotter
image: "registry.k8s.io/sig-storage/csi-snapshotter:v8.2.1"
args:
- --v=5
- --leader-election
- --leader-election-namespace=democratic-csi
- --timeout=90s
- --worker-threads=10
- --csi-address=/csi-data/csi.sock
volumeMounts:
- mountPath: /csi-data
name: socket-dir
env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: csi-driver
image: docker.io/democraticcsi/democratic-csi:latest
args:
- --csi-version=1.5.0
- --csi-name=org.democratic-csi.iscsi-synology
- --driver-config-file=/config/driver-config-file.yaml
- --log-level=debug
- --csi-mode=controller
- --server-socket=/csi-data/csi.sock.internal
livenessProbe:
failureThreshold: 3
exec:
command:
- bin/liveness-probe
- --csi-version=1.5.0
- --csi-address=/csi-data/csi.sock.internal
initialDelaySeconds: 10
timeoutSeconds: 15
periodSeconds: 60
volumeMounts:
- name: socket-dir
mountPath: /csi-data
- name: config
mountPath: /config
- name: csi-proxy
image: docker.io/democraticcsi/csi-grpc-proxy:v0.5.6
env:
- name: BIND_TO
value: unix:///csi-data/csi.sock
- name: PROXY_TO
value: unix:///csi-data/csi.sock.internal
volumeMounts:
- mountPath: /csi-data
name: socket-dir
volumes:
- name: socket-dir
emptyDir: {}
- name: config
secret:
secretName: csi-synology-democratic-csi-driver-config
nodeSelector:
kubernetes.io/os: linux
---
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: org.democratic-csi.iscsi-synology
labels:
app.kubernetes.io/name: democratic-csi
spec:
attachRequired: true
podInfoOnMount: true

View File

@ -0,0 +1,93 @@
driver: synology-iscsi
httpConnection:
protocol: https
host: storage0.pyrocufflink.blue
port: 5001
username: democratic-csi
allowInsecure: true
# should be uniqe across all installs to the same nas
session: "democratic-csi"
serialize: true
# Choose the DSM volume this driver operates on. The default value is /volume1.
# synology:
# volume: /volume1
iscsi:
targetPortal: "server[:port]"
# for multipath
targetPortals: [] # [ "server[:port]", "server[:port]", ... ]
# leave empty to omit usage of -I with iscsiadm
interface: ""
# can be whatever you would like
baseiqn: "iqn.2000-01.com.synology:csi."
# MUST ensure uniqueness
# full iqn limit is 223 bytes, plan accordingly
namePrefix: ""
nameSuffix: ""
# documented below are several blocks
# pick the option appropriate for you based on what your backing fs is and desired features
# you do not need to alter dev_attribs under normal circumstances but they may be altered in advanced use-cases
# These options can also be configured per storage-class:
# See https://github.com/democratic-csi/democratic-csi/blob/master/docs/storage-class-parameters.md
lunTemplate:
# can be static value or handlebars template
#description: "{{ parameters.[csi.storage.k8s.io/pvc/namespace] }}-{{ parameters.[csi.storage.k8s.io/pvc/name] }}"
# btrfs thin provisioning
type: "BLUN"
# tpws = Hardware-assisted zeroing
# caw = Hardware-assisted locking
# 3pc = Hardware-assisted data transfer
# tpu = Space reclamation
# can_snapshot = Snapshot
#dev_attribs:
#- dev_attrib: emulate_tpws
# enable: 1
#- dev_attrib: emulate_caw
# enable: 1
#- dev_attrib: emulate_3pc
# enable: 1
#- dev_attrib: emulate_tpu
# enable: 0
#- dev_attrib: can_snapshot
# enable: 1
# btfs thick provisioning
# only zeroing and locking supported
#type: "BLUN_THICK"
# tpws = Hardware-assisted zeroing
# caw = Hardware-assisted locking
#dev_attribs:
#- dev_attrib: emulate_tpws
# enable: 1
#- dev_attrib: emulate_caw
# enable: 1
# ext4 thinn provisioning UI sends everything with enabled=0
#type: "THIN"
# ext4 thin with advanced legacy features set
# can only alter tpu (all others are set as enabled=1)
#type: "ADV"
#dev_attribs:
#- dev_attrib: emulate_tpu
# enable: 1
# ext4 thick
# can only alter caw
#type: "FILE"
#dev_attribs:
#- dev_attrib: emulate_caw
# enable: 1
lunSnapshotTemplate:
is_locked: true
# https://kb.synology.com/en-me/DSM/tutorial/What_is_file_system_consistent_snapshot
is_app_consistent: true
targetTemplate:
auth_type: 0
max_sessions: 0

View File

@ -0,0 +1,32 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: democratic-csi
labels:
- pairs:
app.kubernetes.io/instance: csi-synology
resources:
- namespace.yaml
- rbac.yaml
- democratic-csi.yaml
- secrets.yaml
- storageclass.yaml
patches:
- patch: |
kind: Deployment
apiVersion: apps/v1
metadata:
name: csi-synology-democratic-csi-controller
namespace: democratic-csi
spec:
template:
spec:
hostNetwork: true
images:
- name: docker.io/democraticcsi/democratic-csi
newName: ghcr.io/democratic-csi/democratic-csi
digest: sha256:da41c0c24cbcf67426519b48676175ab3a16e1d3e50847fa06152f5eddf834b1

View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: democratic-csi

316
democratic-csi/rbac.yaml Normal file
View File

@ -0,0 +1,316 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-synology-democratic-csi-controller-sa
namespace: democratic-csi
labels:
app.kubernetes.io/name: democratic-csi
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-synology-democratic-csi-node-sa
namespace: democratic-csi
labels:
app.kubernetes.io/name: democratic-csi
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-synology-democratic-csi-controller-cr
labels:
app.kubernetes.io/name: democratic-csi
rules:
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- list
- create
- apiGroups:
-
resources:
- persistentvolumes
verbs:
- create
- delete
- get
- list
- watch
- update
- patch
- apiGroups:
-
resources:
- secrets
verbs:
- get
- list
- apiGroups:
-
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
-
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- update
- patch
- apiGroups:
-
resources:
- persistentvolumeclaims/status
verbs:
- get
- list
- watch
- update
- patch
- apiGroups:
-
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- storage.k8s.io
resources:
- volumeattachments
verbs:
- get
- list
- watch
- update
- patch
- apiGroups:
- storage.k8s.io
resources:
- volumeattachments/status
verbs:
- patch
- apiGroups:
- storage.k8s.io
resources:
- storageclasses
verbs:
- get
- list
- watch
- apiGroups:
- csi.storage.k8s.io
resources:
- csidrivers
verbs:
- get
- list
- watch
- update
- create
- apiGroups:
-
resources:
- events
verbs:
- list
- watch
- create
- update
- patch
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotclasses
verbs:
- get
- list
- watch
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshots/status
verbs:
- create
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotcontents
verbs:
- create
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotcontents/status
verbs:
- create
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshots
verbs:
- create
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- storage.k8s.io
resources:
- csinodes
verbs:
- get
- list
- watch
- apiGroups:
- csi.storage.k8s.io
resources:
- csinodeinfos
verbs:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- watch
- list
- delete
- update
- create
- apiGroups:
- storage.k8s.io
resources:
- csistoragecapacities
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
-
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs:
- get
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-synology-democratic-csi-node-cr
labels:
app.kubernetes.io/name: democratic-csi
rules:
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- list
- create
- apiGroups:
-
resources:
- nodes
verbs:
- get
- list
- watch
- update
- apiGroups:
-
resources:
- persistentvolumes
verbs:
- get
- list
- watch
- update
- apiGroups:
- storage.k8s.io
resources:
- volumeattachments
verbs:
- get
- list
- watch
- update
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-synology-democratic-csi-controller-rb
labels:
app.kubernetes.io/name: democratic-csi
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: csi-synology-democratic-csi-controller-cr
subjects:
- kind: ServiceAccount
name: csi-synology-democratic-csi-controller-sa
namespace: democratic-csi
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: csi-synology-democratic-csi-node-rb
labels:
app.kubernetes.io/name: democratic-csi
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: csi-synology-democratic-csi-node-cr
subjects:
- kind: ServiceAccount
name: csi-synology-democratic-csi-node-sa
namespace: democratic-csi

View File

@ -0,0 +1,73 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: csi-synology-democratic-csi-driver-config
namespace: democratic-csi
labels: &labels
app.kubernetes.io/name: synology-iscsi-driver-config
app.kubernetes.io/component: democratic-csi
app.kubernetes.io/part-of: democratic-csi
spec:
encryptedData:
synology.password: AgC6Ai4YXYUZZ0ve8MwzeWFb5QzLbCunHOhjela/TGCzPr48evXbj6wKKVIailXS2cpD948wQ9tEX5bK3ojlMIuuzjbux0ATpTuSN81JQPbvArINp9kYu/QK2Eg46tEk6f5W1VFVC2yYQySC9+7NLJRg8qk8gGUGUMt11mRcsyJ6iBnzEt+5xwK+adQB0/pHJPGGKKcOJY9ZUCdl+Q930ZvnSvrdZNcFKH1meFww7ujQ0NBV8ABpcJwEjJhfFi3tMBKpIPrYGsSVEmHYciwK2YLyeJ/Ao7GBIBKX5lIQl0aTi40oIsc3BV2ZTmM1a2ZuuQWg33+9/r3FaU6ZdYL84B9S+W6IG893yFH+22fcArxCzjVnb8oftzrl2J/M3UZhtL4vYakHjEVMqCm2hzHjGCAadXD1cs6xiqcl4mA40KbaEojxodZJyzlNBbTi4ZN4cIaIFO8FNYnewSXtYZBIUzgdNe65k9orpmaV+qpK4Q8Cd3uZg4RQwiygBPQE9BGSJ7cBc/dCqxevuZB1F1yOetpPlQgyIN6gixt6xzefPp0VWY1I1TI3kjLSRiRGWUK1NIL4J3TIdcBsuO8OXWh0D2c+n4/dIPX9peCN8COKXMwjBm9AHDZ1ImlnVZrAxzYCTPxtGRtJVp/4pW6aDWXCA7UWPdKroipw9FUAK64knqMoV7QS7c6Kw7cz2ajvAV84O/jNkRc7L20J35z30rSncH7l1/JV0XPOZh0XWE5068TQKQ==
template:
metadata:
name: csi-synology-democratic-csi-driver-config
namespace: democratic-csi
data:
driver-config-file.yaml: |
driver: synology-iscsi
httpConnection:
protocol: https
host: storage0.pyrocufflink.blue
port: 5001
username: democratic-csi
password: {{ index . "synology.password" }}
allowInsecure: true
session: democratic-csi
serialize: true
iscsi:
targetPortal: '[fd68:c2d2:500e:3ea3:8d42:e33e:264b:7c30]:3260'
baseiqn: iqn.2000-01.com.synology:csi.
lunTemplate:
type: BLUN
targetTemplate:
auth_type: 2 # 0: None; 1: CHAP; 2: Mutual CHAP
max_sessions: 0 # 0: Unlimited
chap: true
mutual_chap: true
lunSnapshotTemplate:
is_app_consistent: true
is_locked: true
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: synology-iscsi-provisioner
namespace: democratic-csi
spec:
encryptedData:
targetTemplate: AgDWYcaVFVlqHO1XCH0d0Okz2RHt1R1pc2ygTtP4ZYuc44IdfERzgGh9CWNbjY+Qf5K7kF4TOIwgRs1MLumaUg637VO7SYCl1kwWV6pZ/g4bLX1FGTl+XFIAH53EKxDD5nC9fl3VG46IA+dYBPoWFb0UYoI09eWHUg7vTRk1/0MTu19UPkc6VafhFXTfVNiUykF+264Ck3I9i9hMk3Buf9+E4qLHeyyfpMob7IRpdkz+ONYYrxHOGrwDgqFwcyiyliIYWjmOh/FV6kolffeNgSkXpWNNrLQOkkSOwUF6DalKiZd16nzLrvzKFWuDcdcRqxBBKaMUF/JK4BAkfi+MNRTaceCmoSkS21gVLbATb0L3Z7JaifdqRInPNMbkFYs+wILkozyJX0JANg4kuMBCW8GfPEMj9ck21dyeR+ucXcIc67GYS7L92d/ITZd2SWT6a6LRT1vBvroE8ybVf+3oOPUOtaSiZsZpNan2DO4kk/1ZD6clBvn5Cz0BqbVQxwwPSuGkvFXNpDX+xliN+QkohnWDQKi4cMvUqVUG7MyfbaCiGyXcH7enYxccBvIVVy6rXWXDtkzP4B30KeO7rfz0eDn7f+zYZPpwFE6TIorCNe+5zNC0uDwMKf7Csz3x78ZxXtYpdPpFpnboP5zWXhKZY4EfgiyV1HDoSAkzfC4zQV26DnH1nfN9OjYwNUdc75tw7VYuSWS8cEH71E9DdvcJv1XL0f7D5uV5RlGQP3sonWhFi73dLuqCNNwHtEOIV3XxJvN/gaoDRvQQMTosWK5pOs3CpiBGq+EYoM5KWZZhp29axSQ3NRefGoLwOsbeEg==
template:
metadata:
name: synology-iscsi-provisioner
namespace: democratic-csi
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: synology-iscsi-chap
namespace: democratic-csi
spec:
encryptedData:
node-db.node.session.auth.password: AgC2kAta4SiM1EcDAVdenwtKLGTrDJte1qSK3W8WO80zKycj54KBlWMvCLzala70/e1e26iRUWotgwUrrPQpYoAspR9kHIaGFccZvVh+JWJY1OIfCryvumN8jGk0ynN5IMo/ZTFTEE76XrEckvnRrZIcqb9K1RlpS5jRPA8vXDGBofXG4in/scZ08SNIsrELfcKvIsSZsYQF6aY3cQ+rcqePJBBG+5hDsu6qsBoib1tsfe2DoCZ2bYRu5BJFD6CneUTCcVvoBBYmMX+nS2Cvfz8OK+5H42q0W3Gzg6VJYrTsQ1PN5LLg5+xk6ENovw/PtohiwvP6RV9I2r6ev+RrrlWUPlC7XOD0qm2nUeG8D8J+9aP2prQ9zFgpuIZ//gIKKvMSsSJRZvSkbjJ6nrC9ViVmaC65dx89bYjr5vB+7Dm5ytQ6ars5rEpEexiPgGiobnCosn0wwMN1WP97VcpW8udqsticLSBFtANUUtnW2yZMRuVh7a2MutnlUXgODG+ZgkNaZE0cELfOynkhaf10aByuXIN1NX9VIdzfIbdZaIKvr0xKQSdKnbszoHQNOZieE4mXZ/w0BiiDilvyqtLP+3Maa+mFIjoo17zlf8PJD1dEUFckNUBJifVIV6vOHCKXO565IxyE9nNokXR7xkd6XEd3qefoV+9IpOt0NEkHehbSZzUy3JpyNbicdF1WyXb/uY9riacLptssZ4LF8eQ=
node-db.node.session.auth.password_in: AgCMw56LgARt7/dn2WhebQIv+uNLkGUxBkgbYOw+Po9eqgk622F7Y6pVWRAwicdPBM2cjnSrGjPO7nzgXhD0GIbW44WyvwM2w+n5klWmSC9prK+Orup3TMty2hKnSMLOR3rIfpUiRJ0NFvGkTvPzQ/ZDX3O4c88oG6UGVG3B4bQu6Kn5GJ5is2XAnh2dipBx18kLpEmL3hMMqpAy2x0qyf8vJxy39ZvAntk69ziliumqpxePecvbLPkkh2A1jwZR0guBDvBiksvoOyh+P7hTxj3ioVC3HZ4+i52tuvfqugo+INqKJfr15k6fA2cTFEHJ8kwkPtFQCA3bbvRAbcjl0malOIqBFBFwbJYvcauXZGP9m1uoMRni3FHn+1YkBdsvSnw66aYHc4gjN8VrLSziYH72TH8XJ6jEikeK5+nCN2+uhC+AetEUFcLCNM7sKXlS7pzIOQiZ3oB7FcQrsSUkt1Zjax5F6i0reRTdZd/qPLvt65NFwjG/a3yMLf141aHSRog+HGugm4/1A2USGmURmwGSVwAjfrK7b/dj3tMOG8BI4vVJ0UCyw65v0R9h4VEORyr4sXTgNx2+5HewEskDt3LyMzmw4Y6Sw2ftZmQxNEsSy+8BEF4zZj6foIAGuLShjI+4BR9aGnX4maL7IjR6cmj6qwinybfFYAMSx23Icw/aXUBgJ6Slgnd6l96g2RWcNGDxWM8Wq6p2W9VHvDY=
node-db.node.session.auth.username: AgBXplj0SXTinhqbpu5SvYJheYt9G4YNGE99UIi2F0n5QrCI7zvuuSQvA8EKCS5LQni+Og/wToJs1wLeUX4OstlQd3OvkpFDD+jrPVUDv04tlSeNJmaMrQe1pNk04GiLJKeDRRkG+9eTYSIKMsDLroofjHgiRH5wsBh0ncWDW1v5cNlpgq3EzgEQiKnL5zIPIXlHKkadZ9cvebtGoW7mGEnPI/QSnurhVfzEWCXCilxvyNDnBNIKK1rf79eDg1+ZecA0bvE2d7d1cfLhKG+Hd7JcRI0fxii+u1KTCBqbl6goCiCUi5KBfCMP45m7DTyMMPNSfsx9WVjR3ueEXucRGIfhTrV5Zo5Y+WY2c4MoW9XDw0JG/zzHJAOzd9CYk2b6EgEhJLXyHdhNp3JfN4lBpbM6r8RIoQTRImLH0BxytIXQ8kzMtJdkYt2rjV4ZR/fQB9UzGYBtLgWTrNbA+PgEBDB5nlVzbCXZ6uxfRadc2jv2fjGvzidIsfFOicrxWTQtnwSqbs8XAOydHU3Kk7Hrv8k22uaFETcz/tZI619wQL63SmA2igM0fBZcuc64Lx6wmzQBFA9CNKVuPHKFdPXM3s4GzrLqKMskAmDpYvtSlvSqsE2nv6sObS8Iyzm4o69V9+ma2LGD5bl6i7L2wiLlgvc8Ef+YviVzn8lVYqdKCce6F/5TQKNzvbdnJ0bJn6Q01CVHlYqbnyworsmf
node-db.node.session.auth.username_in: AgCT8KR/4GNoDa/TIv6YykoDaGKIP5yXkC/krWFYU5lBMSc3DreECmmow88/5xB4v+5dVt9eE7bJkgPqsUVNXlzDXpSSB/TS2iM/3sAd4ZHzZroTLIf+0QnDC2ZrybokcdmCjkFUgnDzJ9Vs+GqjUjL97LHPbTMc8ONwgiy6YmKLpc11V+JxWqSsKwGPM9ObdmI9rh/IZa19sksh86va3oqjDfElXEwKFkztV1f/NHCsWsuuov/Ku6Lisk5X0JIMKPTUUza0q3tZlJ/NotxNydHef+PA9R648XURQs/xp/hzrdttuMzxo7gT0YEsr8y9h7xlTPlR8we7/igjUMmS+ORRafg5m6PpHWanDxtHafhw9wfmvh0wEgXjC8Sz6Ub3Q9idBlHock60h+uyfsdlP3A2qMjdUXr0dFNBwXcGTaM/n5T18gO05/JSUv7CEdiuSlMnPjYzChAHDSCzxblk8CRDTcSjsSMvVBPjr5L+KQqGj3f6mm3lQnPwzXprS0//SsehRReAvbX5eGfd8Bu8nhRRtgEXvLqQdC7WxbWe0QjwB5ZRHt/4v5N1K8TXo8h6iZ6fcEtTfloMH07TitdwdYQm4uG7dfA7PA9KuqDs+R+phGFGWuzq1cMtp+hOJ6XpFgGyVhYAL/lyl3DddT1o9o7UhDCi4w7nSyxVamwyaGuUsF3lX2TyGVPjdGN1D5dlhRJ8YSPMDWOrZw==
template:
metadata:
name: synology-iscsi-chap
namespace: democratic-csi

View File

@ -0,0 +1,20 @@
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: synology-iscsi
allowVolumeExpansion: true
provisioner: org.democratic-csi.iscsi-synology
parameters:
fsType: xfs
csi.storage.k8s.io/provisioner-secret-name: synology-iscsi-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: democratic-csi
csi.storage.k8s.io/node-stage-secret-name: synology-iscsi-chap
csi.storage.k8s.io/node-stage-secret-namespace: democratic-csi
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: synology-iscsi
driver: org.democratic-csi.iscsi-synology
deletionPolicy: Delete

View File

@ -27,6 +27,7 @@ spec:
tolerations: tolerations:
- key: du5t1n.me/machine - key: du5t1n.me/machine
value: raspberrypi value: raspberrypi
- key: du5t1n.me/jenkins
volumes: volumes:
- name: device-plugin - name: device-plugin
hostPath: hostPath:

1
dynk8s-provisioner/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
wireguard-config

View File

@ -1,196 +1,3 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: dynk8s
labels:
kubernetes.io/metadata.name: dynk8s
app.kubernetes.io/instance: dynk8s-provisioner
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
automountServiceAccountToken: true
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dynk8s-provisioner
namespace: kube-system
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dynk8s-provisioner
namespace: kube-public
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- configmaps
resourceNames:
- cluster-info
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dynk8s-provisioner
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- nodes
verbs:
- list
- get
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dynk8s-provisioner
namespace: kube-system
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
namespace: dynk8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dynk8s-provisioner
namespace: kube-public
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
namespace: dynk8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dynk8s-provisioner
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
namespace: dynk8s
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynk8s-provisioner-pvc
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner-pvc
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: storage
app.kubernetes.io/part-of: dynk8s-provisioner
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
--- ---
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
@ -246,8 +53,7 @@ spec:
serviceAccountName: dynk8s-provisioner serviceAccountName: dynk8s-provisioner
volumes: volumes:
- name: dynk8s-provisioner - name: dynk8s-provisioner
persistentVolumeClaim: emptyDir: {}
claimName: dynk8s-provisioner-pvc
--- ---
apiVersion: v1 apiVersion: v1
@ -268,54 +74,3 @@ spec:
ports: ports:
- port: 8000 - port: 8000
name: http name: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
spec:
ingressClassName: nginx
tls:
- hosts:
- dynk8s-provisioner.pyrocufflink.net
rules:
- host: dynk8s-provisioner.pyrocufflink.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dynk8s-provisioner
port:
name: http
---
apiVersion: v1
kind: Secret
metadata:
name: wireguard-config-0
namespace: dynk8s
labels:
app.kubernetes.io/part-of: dynk8s-provisioner
dynk8s.du5t1n.me/ec2-instance-id: ''
type: dynk8s.du5t1n.me/wireguard-config
stringData:
wireguard-config: |+
[Interface]
Address = 172.30.0.178/28
DNS = 172.30.0.1
PrivateKey = gGieVWS8SUQxC7L0NKmHlpvBTANNNaucsm9K1ioHPXU=
[Peer]
PublicKey = 85BW2bagvhOZnvFD6gmjnT+uUj5NaF4z+YFBV/br9BA=
PresharedKey = bZgUN82zDW7Q+558omOyRrZ0rw3bUohmIjEaxgtZCv8=
Endpoint = vpn.pyrocufflink.net:19998
AllowedIPs = 172.30.0.0/26, 172.30.0.160/28, 172.31.1.0/24

View File

@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
spec:
ingressClassName: nginx
tls:
- hosts:
- dynk8s-provisioner.pyrocufflink.net
rules:
- host: dynk8s-provisioner.pyrocufflink.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dynk8s-provisioner
port:
name: http

View File

@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
labels:
- pairs:
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
resources:
- namespace.yaml
- rbac.yaml
- dynk8s-provisioner.yaml
- ingress.yaml
- secrets.yaml

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: dynk8s
labels:
kubernetes.io/metadata.name: dynk8s
app.kubernetes.io/instance: dynk8s-provisioner

View File

@ -0,0 +1,164 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
automountServiceAccountToken: true
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dynk8s-provisioner
namespace: kube-system
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dynk8s-provisioner
namespace: kube-public
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- configmaps
resourceNames:
- cluster-info
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dynk8s-provisioner
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/component: http-api
app.kubernetes.io/part-of: dynk8s-provisioner
rules:
- apiGroups:
- ''
resources:
- nodes
verbs:
- list
- get
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dynk8s-provisioner
namespace: dynk8s
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dynk8s-provisioner
namespace: kube-system
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
namespace: dynk8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dynk8s-provisioner
namespace: kube-public
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
namespace: dynk8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dynk8s-provisioner
labels:
app.kubernetes.io/name: dynk8s-provisioner
app.kubernetes.io/instance: dynk8s-provisioner
app.kubernetes.io/part-of: dynk8s-provisioner
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: dynk8s-provisioner
subjects:
- kind: ServiceAccount
name: dynk8s-provisioner
namespace: dynk8s

View File

@ -0,0 +1,16 @@
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: wireguard-config-0
namespace: dynk8s
spec:
encryptedData:
wireguard-config: AgCRjcXhRNtDg/LSmDKFxbSunGGNBu6GrHGYIPG+DMXCbAIiRnnjxpeu/7Vh0WrYcHCHoLdm0NAr7M9G7S8aS8XUDZ7ANphGk56t8Mrrv9ZzOwHyCnxm3QM6q7RNus2+PgKJ/zNe8j5M1u4v3wGk1XzXPtYQ4dRp6op5X+ILGUu16Y2/hcfHEtW9IupqCKgteo1GAyHY4I86ldsTSIvEtcriVhXrEIYYRwYzEpR06y15dbz4qC86nTDp0RuhO+eU4hEzu/c80IJIjTz5CbDundSYRLqafZgs+LwL2fo5wnVyDy1KfP5X2o2mbZFz/5fhwj3M27/g+4KLh08NY5DJTMN1CFrHYGcWUbpIqWYCEJd8c40jRzzDVhcHA3WJjOd0KZv0oRfwmjbBlf0mMxDcJhG/h8tngQBs6aNEpq69RbABbL0bBkIQBokmib4bSfppHTBYNhzbdLwDQJD072qqNGKbDufHkcK4bBwuvmeE00EKxqFoqz++6EQMRkuNN7UtpFDKyDxElOMlo09KKGMUqz/JkFPb4YRJhF31+CskWmU1AVFge7Z5sVe5lMiDpoH62Zg5sxRSaHbdYvsS1vxsTfdG3rmhOAMxxYc+Kvt3u3eNkzEV3lUosorspZhBnEzyHHcap1QUd19vVarjv77g9Br7PATOl3SmuK58JqW2dyOiMQvjLNUAZ27q3uEZGAzRZ8yg5RoejFpueFJjSjTnV1UFdH/OseHXgvFd60syg/mviIA9IGzaxCjoZfxL1GlfjGDYsetnnIDCcQR8K915Qh0PfMdwHKsPBmmDGAxP7k/DHEM3tYC66SQAD4mpMH4Ri8jDD3ijpq8ud93CZX5S32rU0yrXIWCM4ByXks32HACCEOIdfHuGuys6FRQTCPFJuYlpwsVTSJKLjy59rTz5B6nLKxtaOuRULh8MrDR7KlhMiE7gl5waiIlYaiecVn/sNfu4q9UfgwGUntKIovmrwcBPjMRmLgs3IQH4p02G4OemPaByXkPD1JROk2epNkLMwH+IsUxAveGy/hCmrLa9fRaJWSlfuAQtqOihf34YBudsfqwr0UGLI8VsVe+p+tF+AYftUGDf1trJTI8TJUB/91CwrC6c61EFbQCJc90w+lL+oJueDZdGXzoYvkCsDpfFMA==
template:
metadata:
name: wireguard-config-0
namespace: dynk8s
labels:
app.kubernetes.io/part-of: dynk8s-provisioner
dynk8s.du5t1n.me/ec2-instance-id: ''
type: dynk8s.du5t1n.me/wireguard-config

View File

@ -0,0 +1,11 @@
# vim: set ft=dosini :
[Interface]
Address = 172.30.0.194/29
DNS = 172.30.0.1
PrivateKey = WJb4G0EL5xc0VMHZeiqJE3G0OlFhe1Q5CEJkMg8hTkE=
[Peer]
PublicKey = 85BW2bagvhOZnvFD6gmjnT+uUj5NaF4z+YFBV/br9BA=
PresharedKey = gVRSPVLZMx1maIfecFIcAeesrireopaKqs0jDj9muS0=
Endpoint = vpn.pyrocufflink.net:19998
AllowedIPs = 172.30.0.0/26, 172.30.0.160/28, 172.31.1.0/24

View File

@ -1,6 +1,6 @@
TZ=America/Chicago TZ=America/Chicago
TRUSTED_PROXIES=172.30.0.160/28 TRUSTED_PROXIES=10.149.0.0/16
VANITY_URL=https://firefly.pyrocufflink.blue VANITY_URL=https://firefly.pyrocufflink.blue
CAN_POST_FILES=true CAN_POST_FILES=true

View File

@ -4,13 +4,16 @@ SITE_OWNER=dustin@hatch.name
TZ=America/Chicago TZ=America/Chicago
TRUSTED_PROXIES=172.30.0.160/28 TRUSTED_PROXIES=10.149.0.0/16
DB_CONNECTION=pgsql DB_CONNECTION=pgsql
DB_HOST=default.postgresql DB_HOST=postgresql.pyrocufflink.blue
DB_PORT=5432 DB_PORT=5432
DB_USERNAME=firefly-iii.firefly DB_USERNAME=firefly
DB_DATABASE=firefly DB_DATABASE=firefly
PGSSLROOTCERT=/run/dch-ca/dch-root-ca.crt
PGSSLCERT=/run/secrets/firefly/postgresql/tls.crt
PGSSLKEY=/run/secrets/firefly/postgresql/tls.key
CACHE_DRIVER=redis CACHE_DRIVER=redis
SESSION_DRIVER=redis SESSION_DRIVER=redis

View File

@ -66,6 +66,7 @@ spec:
containers: containers:
- name: firefly-iii - name: firefly-iii
image: docker.io/fireflyiii/core:version-6.0.19 image: docker.io/fireflyiii/core:version-6.0.19
imagePullPolicy: IfNotPresent
envFrom: envFrom:
- configMapRef: - configMapRef:
name: firefly-iii name: firefly-iii
@ -73,8 +74,6 @@ spec:
env: env:
- name: APP_KEY_FILE - name: APP_KEY_FILE
value: /run/secrets/firefly-iii/app.key value: /run/secrets/firefly-iii/app.key
- name: DB_PASSWORD_FILE
value: /run/secrets/firefly-iii/db.password
- name: STATIC_CRON_TOKEN_FILE - name: STATIC_CRON_TOKEN_FILE
value: /run/secrets/firefly-iii/cron.token value: /run/secrets/firefly-iii/cron.token
ports: ports:
@ -129,6 +128,7 @@ spec:
spec: spec:
containers: containers:
- image: docker.io/library/busybox - image: docker.io/library/busybox
imagePullPolicy: IfNotPresent
name: wget name: wget
command: command:
- wget - wget

View File

@ -9,11 +9,13 @@ namespace: firefly-iii
resources: resources:
- secrets.yaml - secrets.yaml
- postgres-cert.yaml
- redis.yaml - redis.yaml
- firefly-iii.yaml - firefly-iii.yaml
- ingress.yaml - ingress.yaml
- importer.yaml - importer.yaml
- importer-ingress.yaml - importer-ingress.yaml
- ../dch-root-ca
configMapGenerator: configMapGenerator:
- name: firefly-iii - name: firefly-iii
@ -26,9 +28,6 @@ configMapGenerator:
- firefly-iii-importer.env - firefly-iii-importer.env
patches: patches:
# This patch changes the source secret for the PostgreSQL database
# password from the default (`db.password` inside `firefly-iii`) to
# a secret managed by the postgres operator.
- patch: |- - patch: |-
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
@ -37,17 +36,33 @@ patches:
spec: spec:
template: template:
spec: spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
containers: containers:
- name: firefly-iii - name: firefly-iii
env:
- name: DB_PASSWORD_FILE
value: /run/secrets/postgresql/password
volumeMounts: volumeMounts:
- name: db-secret - mountPath: /run/dch-ca
mountPath: /run/secrets/postgresql name: dch-root-ca
readOnly: true
- mountPath: /run/secrets/firefly/postgresql
name: postgresql-cert
readOnly: true readOnly: true
volumes: volumes:
- name: db-secret - name: dch-root-ca
configMap:
name: dch-root-ca
- name: postgresql-cert
secret: secret:
secretName: firefly-iii.firefly.default.credentials.postgresql.acid.zalan.do secretName: postgres-client-cert
defaultMode: 0440 defaultMode: 0640
images:
- name: docker.io/fireflyiii/core
newTag: version-6.2.21

View File

@ -0,0 +1,13 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: postgres-client-cert
spec:
commonName: firefly
privateKey:
algorithm: ECDSA
secretName: postgres-client-cert
issuerRef:
name: postgresql-ca
kind: ClusterIssuer

View File

@ -1,22 +1,3 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis
namespace: firefly-iii
labels:
app.kubernetes.io/name: redis
app.kubernetes.io/component: redis
app.kubernetes.io/instance: firefly-iii
app.kubernetes.io/part-of: firefly-iii
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
@ -75,7 +56,7 @@ spec:
runAsUser: 1000 runAsUser: 1000
runAsGroup: 1000 runAsGroup: 1000
volumeMounts: volumeMounts:
- name: redisdata - name: data
mountPath: /data mountPath: /data
subPath: data subPath: data
- name: tmp - name: tmp
@ -83,9 +64,21 @@ spec:
securityContext: securityContext:
fsGroup: 1000 fsGroup: 1000
volumes: volumes:
- name: redisdata
persistentVolumeClaim:
claimName: redis
- name: tmp - name: tmp
emptyDir: emptyDir:
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
labels:
app.kubernetes.io/name: redis
app.kubernetes.io/component: redis
app.kubernetes.io/part-of: firefly-iii
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2G

View File

@ -21,7 +21,7 @@ metadata:
namespace: firefly-iii namespace: firefly-iii
spec: spec:
encryptedData: encryptedData:
dustin.access-token: AgBqtl9wO0Xb2fbyBm7SJanNvCy1bpJyE83nZQpNIpOoNLkBmi3lkBHYRiEpF71lhcd24cdv2f8BWfjoxXe31smzzAoHHGR7vfPyjI2ufXHs5R5lHu/bmC/8Xbp6XaKHV7KhqdsIuPkbZmZGdRccoQAwUWQzjMqVgu7s9pDDKl+XV0bBgFs+LejF0e+PEEyXCSaF8nWy34MWKGW3SgsXlk4QPqJ426DA1TRwsEVsIWBGeqPAAXorDPk4FDmmpELg/jHbrISHSjiFneL3E9bogoPgPBX51XUjU6dupq2XJ1pK70SFMT/AnqgUtGYRyDpJCLe6yEp/IPAXHBgwkWNt+qT+LagY1/3Y+2lvct47N/+jWuqw0aPbpciZjswiO8Q7zGJsGTYKrf1NWNwuruYb4kyNbRPJclnQN+QsQEfVYHugtDClDxbOAj1zJM9kG6t9H5mwAr9lsCrs1Oqc6xFLMMmzjWnOaauwAepVVseJCTz1fkS/VKMDW6WRu1H6DUbmBqaHpA6mgL+CDg2xFeZrqdkYKPKWPjo+y1KDfHDiwxqJ63NDdqQvBFrJg0UrRAetAbCeNlCgZJwWmgTh149MJrxGGb4pgxC7rd+AC0qLs9druzyLbHTJkn0JIySy9NuRNGJmrr3WBOUteOT8el+yEg2X37k6Eif7ABBrnibtdUXd+feaVp9pkMIxBM8fyrneNAyX6cpjQ9cwKNEq85VWfu6569x6ZhJAr1lOXUWGc12mdg7ELWoTBkrt0dCjlLzOO+NvP4wOn3Nk0nszs0lP+xpD2etjfVLpIIhg2p/4nutxCU/ZV+JMIqzDOyFH/gJH3k1QW0VgbseLSmE2tQE33ImFCDc2/7NgkHltMl2FYSglVWr9R5s0nlz3u1/wrGHoF2tok5v/aE1ZYPZh4Gcr9KBzxx5uGdy/aUFTntYXLTJ4i2rMRzwKS7QXMycnsD9huHU2nwNDGWW1Hz66Aj0vysCRIZ4vSYPpMZ+Wu/Zxmkd8KoLE8yJ2Ii/0P6B/VvqFcLBokvG59iPjyPH/RVrDwn4CXelpYT1ojA8MFer0t9Gz5htZsgVVgcDQT4FLccjkFPbiyUou0O2cz3xUIUJrIC4YO6Iu57F1F8AzxxMrsS20VJbD8PkgATuMZos755Ze3k8J7nAXQKlBF50EQ65TYwnvyk+GK6yUtbdCn6Y/1aLYWj3CAROg60yokqiOPVT1gn113FmUvmPCWsKVpAjBvc1vJ8BQChCSYXJQaib75z+/zxN4+Celqxls4zLGJDUMNaXjI1Vf3J9vcGLwUUN1ZjofwJzbx3f3l7VqN3HSPw76jq6XNJbWIdxD0Q+KRjwyZf/uAoWDZULuFOZctOvCxIXCvbUX/6IdJNjIvENuvFY6mE9uyVaDWQGLkDIxGk40Cjyyjvwer96LDod70kg6Rh9vlWTl06UFFm1S6QxWbHB6tsU1SAooihiEeSp1QGyRI2YVRDJvNXoNd0Fbnw4xPI2tQHW++GJpdzeoBuHoDo9a6sDN+WBorQQdNukAJkVlhvprYH5qeLN1ealaDehPv0baECHGKp92kSRpgT9lfoztkOsICruT+b6iDpNU8HejkRH8iB+OZJEADdCDdxX17HKxXi4Sd9c1F5/s9VtSSC3lH11V9mSlnSlgEu6omgnXs1VsmSy4+nvSUSECMFdYK4rgDlyqilyRFKmt6n/g3VchjvFmuWkHTzV1itrAL/51OHwcK79prQVeVD8r3M6U5ap2+hKEdo3blayP9wm/4eeJn2O2S/E0uVKqKWCWpYlQw4TYjO7owAVWuAtaDRn48ZrBqnnvGjn1unlb6OUDTjRmxM9PCWUGSK/T0ouEzErPg9vjYhrVPf3eaJRQ5OrhKZ2YMfYvSUXBGo7fKbegzTzqdCXWQ/a0WiHCxmC4ua5g+h03mtNFU9bu8anSa3p04a1cqZbXZ1s4dMpQStGaLc6p3n3ZtEuleJG7oYhdn9Ys8Ukw1ScQTZ14bjzTm5rZLEMJvdZRPQ== dustin.access-token: AgAEv1RHTUGZBoxDa4nMOZ+gU9sW/SjTdaQ5NAqoFuVOYwlrXMLKubonXduiLXp2YSduuRCsF/X8GH8xLjsegf+zcDZcWPUjUq6Hm7q2KDPmy+Ekjv5Z3IOmBOtQLcPZlJGOeJenHhNu+UyA1G9prBEiXj9PnfMh/RrT6nGU4pCxw3406p4YCvhwh00DhNYYQu8VaFejxkWB9RRQ/sQ54708VxCd9myxKfS5oSbi0+3z20cTfk5mGZs6bM+dbvL994cAUIGViNpnqiT1HFvWwvI1ItRFxhp6/CjLfZh9CRKsz6JnaA1JV8+mU6903yNAU8HjTIJlJNL3+vW9lRwUSCnd1Bghfz+iRpyuV+jaCZD76FrOKTlOr4Eo3M6U+HgSx+1ivamnwDAp0K/EpK3BjW2P476NqCDc10uxmN/gdxsSHDtL2XP91t94ApXQ9xq5/3a6lAOldqYJodg2/EKvwpEjsFlfU1/JgUPyZ6qryDQQpY8o2d0f9GOqVINEjH0Lw7zW4GxutWipw3zKbmN+6OoJyhF4FDRNXDCkI8Q4TVEN05nzSipmWzVmgyeSPLwRW6IJ/uzTGDHVYWGMIXfag9zfDP9X6t4j+81n2MRcJoLPjHgkbsJvo9+yEPnHkwp7WbkBMlEwsDVVSkRDv3bo7BSzOxNqVR7MWlfadbAHkX7HAb7Evj6i1Aq/qLtIp6ubdeYlTgQ/Xjs2k0WjfIIXQAsU4WvelRKqoVJKhTkRDo3SFuRqVYRCQQkPVIZhmmcdzXhemUBpFiRjqLV8IaXOXSXR0jOTp+DDHj7vonwygnMaTRkTwUH5yZw1X74vrZf01Yl6vC+ih6iZk1bwQiPKSfZS2XUZhO9df/TDleBHB1rucLo5dWm9GUIg/GqOc5hcbEmE+0zEA9tdXI5eYTPsKfPLBJic+ej/9A+Qx6aIpylFWVwcYS56Ks/RejHCnA5vq7pE4N8SsOLbcxkvETSEHn3xi1p5YMDF9IeMw2gqGzVT8WZzdhD5MxV4jRvk1LnlRli8SN+G6JEifc219c030YVDuGIU4wO3cmjUoD6QXAK8SIUrjsUbci1T5TEbNjcJtaDxwBHKUvFNaDKvDdKTOYbvRjgQaAmFx0TBu15SPLugrHdD7nYsGwKMUusIRT8K9RxTMuvqwzS0vvn0GBmlrJsny5LlaDuknh2+3KpPUe/P+ZNmnsCG0l48Bw87jkxHeSWzGPMDiFqwpuYA8aDkxW2GFehQEIXefzmz6JOBdlvWsh/BxcYsO1Fch9M0jO1EVS3wDJkbseUs9uIzl6Xs1wbvgrIzDe1qKWdLTt5hLexcsYAcsNDygV4IOpJX+D+yqsRY1BKKbKyBUhEfe7dtbyljM5skfEVjDRpmcPyjoer2/rTVf/Z+DLXgL7kYi0hjrAjeVMaeHx3HJcEYmuVuDsilmjcXeArNB/mvL9wbq8FHWiiGpjNKFlHXUaQFfejGJlIwDT5Zb4GuEpLLYJNt0fUi3zBHtq3/YRk560r0Rw4NjjsBfiUddoY2HbRR7miQub6FQ6NJqTZdezvHn2AX3ggb58OpQZw+qPuL4+/QBCDmIV5p7W1FbdaGnb5+5rEva5qidAErvWfWqaJgtCqbHSCgtF3zbEJFppaPS/ukluEjaXfx24d4NkxVilFWlyaMcTdP6OwLrfnZhf1unmv3QqeNHvcp/bNbVwQqQGLDffCMK5j1X7k4m3mchm09C6C7ZUr7p851y7nouNbWxlEI1DCJ0tPARj8KPvYs/j8nr7Hj4KZO4aCQRM8xbWaGO9hiZNm8IAF5L20T24Icv1kWyDAQC2qretr9rzXdNnQtdbj7UJ+U4MlDffUBpPG9m/plRlyeRK3zR91yaJVxU8RpGrE2pn+h2zszMCbhqSMQuD0hFR7W5LYD4bJniVNaU9WempvfMJHicW7lpX0z38I/zA7eYf1ouOmSNDvS/2hPUAEGZGPuRlDQgc1XIVhFT2N2BvWMbA8pMazpWPXzMvjCwLrSmmfuUlApxA==
tabitha.access-token: AgAvnbZFQl98pnAdjAQMRBrUl54L4hE8meGr4lOP0Ah/O3/xyYi9gHJTOmCibxZH/OGo90KFcOjHplosAAVIvaU5Byp7EkxkWySG+XWu5eEvijxsoEXkmuD5ET9BK5Z5rPzCLG+Dodp7VfwuKETk9te++1UGcfG6rAy5wyqnPSC9mns2xhlb0GLvq1QQdMfrQbEFiOtX5jRcN2Rq57nERlDrpyXkkmpQHh8Qn68qH/Cn2zy6GP6wAxIMEOI4TqZ0Ct0UB+p4Vm0ZYOq4A4ruZTSc61PUfD6BfMH7MswO7dArkfKr0b4s8/rPx1cuJcNVE5ZK1JoiYtAY9+36L5aqYjdNWEWj6b5fmG2QjoAEZ+nynLaYyipFlkkPAjcBMifXe5hK3r7urdPYtBGv/rpHC20dTnNQQqonGdJHkYpXN3rqPImc7XBZWjDUzP2wptzV3PigFfuQdcM+JNUAPLHXK6H1CTNGLNd4pyxXkZc33nvCtUICANtDzbNDqBrzAdrMmnBiySlhQuig/iVgql6/2HFKlo5Uf77Kwhu/V4opkVVfbKpfrLQeZaY+UaQi9N0IyhC0VMgzQ3Lr8P7nEYYc4zfrQlyZGlqW9qLt86Jtj359yZk3L0eGzkq/zKVgw4sOSTt+wmR4ZTBo4OVJelolx9ctPC6MWbW7HCBQhViGNBDb0Sh7OzWy13D6xy8+5t+85XiaW6fGstque62Bteo1nywds7WnPXutyPyteCvQx5d5XGKdurjSzvm37ho3ianbDwpyC6zOVnba7mXbwYtdogevTO8TPjyj+Dm30I9ac4MzStLkziC0ZqKViwadhQZ+rNXwiwMdhbVUmAVOs+XsodTpfLTOKT3wJK4hZ5lHIX8GFxTsmChr6N7+lE4O6/BRczEdFOVKqeErGDVSj/pPnx9DVBUnLLnsXL4jPFEMZJmUht19wAFuH15VQTTSYDb/GL7Bq/ECwniqwkD+jd/fyMTLQSaxrs403b+bHpxAja687632Tvj9Ob2jsolSIWR7gYhqGh3PDqhS1yHU0DiA12t04AieW/NENd2KRnHIRI3eaZow6wzZRx28yeCO0ZqCaEFCZbtKjtvw9D7weist+UnX9MQFC+gbS0yu3wjrW61WpY04Ujsxwh4nKlbCVyhxMvXdx2xrcPkzgLi3ZumAIp028JteDHZBiVcGL4riVlM9VYp5JyL70G5ueUR1H18namVolyALkrM+dsanKdV7LRXc1fK0OODl0nMAGTV00koYFbkeIgVkObgmg5RNnxiE65f73SntI4PjJOem5E4VyBhIb5PFM7Ixxp/BOHI0dr1zITjNC8DyvQ37SYcjYwqCKS6rufBhQQUAq+xlwsX8zXAdPsu8W39+ei4EoFAdV9QpLH4zFvUdD9noimW+s9H3y+JQcJ070LzzvE6snHJdHCHvONuuQ0XFRjEf7Xf2ISZA6dt7i6J/040VTOcrf3JVpcxYdjPRhZZsM6Loti9tNVHWx1UzNZq6NrhnuFrNiYrWyf0wKaaMALwYT6e1KDOhgg0wWR5l18ia8GmtIZ78GQHRojlBWV+blpAM/cS5NHtgL3cRm+9Ep9/KGT2izxJ0gTyXH/DOIbA+NMM4wJT8SWweVbELvyey8br34oIbpv/gOX7C8Qh1h8IOuMPowsqt3IPPjPXyWp9bNLvtXlnFh95VptKW9cm5IR90ATFpzVE8CB04NMu2CYkxtbAuRLPZZWHwN39IeUluRQIEPqJEVhjWthyApJovfuagjcWMRVPbMJddRx+ubYwV1ikjwl8dH2ZT98bcJDN/6mbh3AimpIR2CKI43kNCHuVqLc6PGgwYG+d8w5CWfXk/2eFrCGhC9rWLjvEUiyb6DOM/R1kJt2eunlFr1EyxlvfJ33cdN3K6uQBpXZ6f73YnWXdkEQ2G20TFvizY2payccxo8GuxkSRSiWTlEM+zOZPm8ayF1Z8DKWKiRxNdZHxO0O8eNXR7+QfNMSerCpFb9abcfC/kP6Du9CgB4Q== tabitha.access-token: AgAvnbZFQl98pnAdjAQMRBrUl54L4hE8meGr4lOP0Ah/O3/xyYi9gHJTOmCibxZH/OGo90KFcOjHplosAAVIvaU5Byp7EkxkWySG+XWu5eEvijxsoEXkmuD5ET9BK5Z5rPzCLG+Dodp7VfwuKETk9te++1UGcfG6rAy5wyqnPSC9mns2xhlb0GLvq1QQdMfrQbEFiOtX5jRcN2Rq57nERlDrpyXkkmpQHh8Qn68qH/Cn2zy6GP6wAxIMEOI4TqZ0Ct0UB+p4Vm0ZYOq4A4ruZTSc61PUfD6BfMH7MswO7dArkfKr0b4s8/rPx1cuJcNVE5ZK1JoiYtAY9+36L5aqYjdNWEWj6b5fmG2QjoAEZ+nynLaYyipFlkkPAjcBMifXe5hK3r7urdPYtBGv/rpHC20dTnNQQqonGdJHkYpXN3rqPImc7XBZWjDUzP2wptzV3PigFfuQdcM+JNUAPLHXK6H1CTNGLNd4pyxXkZc33nvCtUICANtDzbNDqBrzAdrMmnBiySlhQuig/iVgql6/2HFKlo5Uf77Kwhu/V4opkVVfbKpfrLQeZaY+UaQi9N0IyhC0VMgzQ3Lr8P7nEYYc4zfrQlyZGlqW9qLt86Jtj359yZk3L0eGzkq/zKVgw4sOSTt+wmR4ZTBo4OVJelolx9ctPC6MWbW7HCBQhViGNBDb0Sh7OzWy13D6xy8+5t+85XiaW6fGstque62Bteo1nywds7WnPXutyPyteCvQx5d5XGKdurjSzvm37ho3ianbDwpyC6zOVnba7mXbwYtdogevTO8TPjyj+Dm30I9ac4MzStLkziC0ZqKViwadhQZ+rNXwiwMdhbVUmAVOs+XsodTpfLTOKT3wJK4hZ5lHIX8GFxTsmChr6N7+lE4O6/BRczEdFOVKqeErGDVSj/pPnx9DVBUnLLnsXL4jPFEMZJmUht19wAFuH15VQTTSYDb/GL7Bq/ECwniqwkD+jd/fyMTLQSaxrs403b+bHpxAja687632Tvj9Ob2jsolSIWR7gYhqGh3PDqhS1yHU0DiA12t04AieW/NENd2KRnHIRI3eaZow6wzZRx28yeCO0ZqCaEFCZbtKjtvw9D7weist+UnX9MQFC+gbS0yu3wjrW61WpY04Ujsxwh4nKlbCVyhxMvXdx2xrcPkzgLi3ZumAIp028JteDHZBiVcGL4riVlM9VYp5JyL70G5ueUR1H18namVolyALkrM+dsanKdV7LRXc1fK0OODl0nMAGTV00koYFbkeIgVkObgmg5RNnxiE65f73SntI4PjJOem5E4VyBhIb5PFM7Ixxp/BOHI0dr1zITjNC8DyvQ37SYcjYwqCKS6rufBhQQUAq+xlwsX8zXAdPsu8W39+ei4EoFAdV9QpLH4zFvUdD9noimW+s9H3y+JQcJ070LzzvE6snHJdHCHvONuuQ0XFRjEf7Xf2ISZA6dt7i6J/040VTOcrf3JVpcxYdjPRhZZsM6Loti9tNVHWx1UzNZq6NrhnuFrNiYrWyf0wKaaMALwYT6e1KDOhgg0wWR5l18ia8GmtIZ78GQHRojlBWV+blpAM/cS5NHtgL3cRm+9Ep9/KGT2izxJ0gTyXH/DOIbA+NMM4wJT8SWweVbELvyey8br34oIbpv/gOX7C8Qh1h8IOuMPowsqt3IPPjPXyWp9bNLvtXlnFh95VptKW9cm5IR90ATFpzVE8CB04NMu2CYkxtbAuRLPZZWHwN39IeUluRQIEPqJEVhjWthyApJovfuagjcWMRVPbMJddRx+ubYwV1ikjwl8dH2ZT98bcJDN/6mbh3AimpIR2CKI43kNCHuVqLc6PGgwYG+d8w5CWfXk/2eFrCGhC9rWLjvEUiyb6DOM/R1kJt2eunlFr1EyxlvfJ33cdN3K6uQBpXZ6f73YnWXdkEQ2G20TFvizY2payccxo8GuxkSRSiWTlEM+zOZPm8ayF1Z8DKWKiRxNdZHxO0O8eNXR7+QfNMSerCpFb9abcfC/kP6Du9CgB4Q==
autoimport.secret: AgAUiScErUsHx0VMhOPaN+onfVz9cm1l00x06713HK4UT/h6Ih/4UcATvXayOsKSVTEzzucNkIaGIgrSG/7RWpo1ZMgqkyjmQI9URUE07yVnckZWWt+JqGTmCS7qp2KLD3eC+VAHuz1/3O3xv5fSW0G1zVJ4pJzaOjyAtWYK59qjL0Mjmcx86Vx6FamNgtcibX5kxO06G2ENeHkYLODeNbdCOwc1p7Uoet9E7zZao958/griN7sx7EmruTu1TLv8UbyJP4/gPlKingX8U6B6QRWeI0L4FkTamrtD3AiTTJnbZ5Gl+o3zbrGc7yxA1gPWqVfi12qwjESQprUQxMVpp6GGtBtCjXNX5Ne0f4y79wP+YRpT2jUdUxi6qdKcw4v018CrEvobSLigBkEYLCVMAmvL0wiZlFosp3MfOd33KBtCQrhoyhJCbJmcS0mEqW5KO66T0Ajqtsc71hGS9LqS5X9mKZHvMLHAM28B4E2MfNnJxABOCBC3Vu+j6nku3qtYkCZl1uk2wF2V5srl8wTuX7a86vDsVJGjBwMT8wXquoIvln+ywkxqAGR0smRYp5xcOZaJ2UfXpodY6+97Quuv9lv4lEwkqzTvieoH3Blw2rV6/Eqjj+1DV+eZX7O3VakDMDV1IWadvRmJjaUmD6z4EChNgNTcOXfAgOpmBa+5uEUH113vZDEM9QWrnz6fDl0kMf6AWDg4jpv9J7qurG927e3iZPXZszYS4CY9ZbMuFNHXsA== autoimport.secret: AgAUiScErUsHx0VMhOPaN+onfVz9cm1l00x06713HK4UT/h6Ih/4UcATvXayOsKSVTEzzucNkIaGIgrSG/7RWpo1ZMgqkyjmQI9URUE07yVnckZWWt+JqGTmCS7qp2KLD3eC+VAHuz1/3O3xv5fSW0G1zVJ4pJzaOjyAtWYK59qjL0Mjmcx86Vx6FamNgtcibX5kxO06G2ENeHkYLODeNbdCOwc1p7Uoet9E7zZao958/griN7sx7EmruTu1TLv8UbyJP4/gPlKingX8U6B6QRWeI0L4FkTamrtD3AiTTJnbZ5Gl+o3zbrGc7yxA1gPWqVfi12qwjESQprUQxMVpp6GGtBtCjXNX5Ne0f4y79wP+YRpT2jUdUxi6qdKcw4v018CrEvobSLigBkEYLCVMAmvL0wiZlFosp3MfOd33KBtCQrhoyhJCbJmcS0mEqW5KO66T0Ajqtsc71hGS9LqS5X9mKZHvMLHAM28B4E2MfNnJxABOCBC3Vu+j6nku3qtYkCZl1uk2wF2V5srl8wTuX7a86vDsVJGjBwMT8wXquoIvln+ywkxqAGR0smRYp5xcOZaJ2UfXpodY6+97Quuv9lv4lEwkqzTvieoH3Blw2rV6/Eqjj+1DV+eZX7O3VakDMDV1IWadvRmJjaUmD6z4EChNgNTcOXfAgOpmBa+5uEUH113vZDEM9QWrnz6fDl0kMf6AWDg4jpv9J7qurG927e3iZPXZszYS4CY9ZbMuFNHXsA==
template: template:

78
fleetlock/fleetlock.yaml Normal file
View File

@ -0,0 +1,78 @@
apiVersion: v1
kind: Service
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
ports:
- name: http
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
template:
metadata:
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
spec:
serviceAccountName: fleetlock
containers:
- name: fleetlock
image: quay.io/poseidon/fleetlock:v0.4.0
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 8080
readinessProbe: &probe
httpGet:
port: 8080
path: /-/healthy
periodSeconds: 60
timeoutSeconds: 5
failureThreshold: 3
successThreshold: 1
startupProbe:
<<: *probe
periodSeconds: 1
timeoutSeconds: 1
failureThreshold: 30
resources:
requests:
cpu: 30m
memory: 30Mi
limits:
cpu: 50m
memory: 50Mi
securityContext:
readOnlyRootFilesystem: true
securityContext:
runAsUser: 842
runAsGroup: 842
runAsNonRoot: true

View File

@ -0,0 +1,26 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: fleetlock
labels:
- pairs:
app.kubernetes.io/instance: fleetlock
resources:
- rbac.yaml
- fleetlock.yaml
patches:
- patch: |
apiVersion: v1
kind: Service
metadata:
name: fleetlock
spec:
clusterIP: 10.96.1.15
images:
- name: quay.io/poseidon/fleetlock
newName: git.pyrocufflink.net/containerimages/fleetlock
newTag: vadimberezniker-wait_evictions

7
fleetlock/namespace.yaml Normal file
View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock

92
fleetlock/rbac.yaml Normal file
View File

@ -0,0 +1,92 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- patch
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
- pods/eviction
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fleetlock
subjects:
- kind: ServiceAccount
name: fleetlock
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
rules:
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- get
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: fleetlock
labels:
app.kubernetes.io/name: fleetlock
app.kubernetes.io/component: fleetlock
app.kubernetes.io/part-of: fleetlock
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: fleetlock
subjects:
- kind: ServiceAccount
name: fleetlock

1
grafana/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
ldap.password

6
grafana/README.md Normal file
View File

@ -0,0 +1,6 @@
# Grafana
[Grafana][0] dashboards. Straightforward, single-instance deployment with
SQLite database (and thus a StatefulSet with a PersistentVolumeClaim).
[0]: https://grafana.com/

View File

@ -0,0 +1,14 @@
apiVersion: 1
datasources:
- name: Loki
type: loki
access: proxy
url: https://loki.pyrocufflink.blue
jsonData:
tlsAuth: true
tlsAuthWithCACert: true
secureJsonData:
tlsCACert: $__file{/run/dch-ca/dch-root-ca.crt}
tlsClientCert: $__file{/run/secrets/du5t1n.me/loki/tls.crt}
tlsClientKey: $__file{/run/secrets/du5t1n.me/loki/tls.key}

View File

@ -0,0 +1,14 @@
apiVersion: 1
datasources:
- name: Victoria Logs
type: victoriametrics-logs-datasource
access: proxy
url: https://logs.pyrocufflink.blue
jsonData:
tlsAuth: true
tlsAuthWithCACert: true
secureJsonData:
tlsCACert: $__file{/run/dch-ca/dch-root-ca.crt}
tlsClientCert: $__file{/run/secrets/du5t1n.me/loki/tls.crt}
tlsClientKey: $__file{/run/secrets/du5t1n.me/loki/tls.key}

824
grafana/grafana.ini Normal file
View File

@ -0,0 +1,824 @@
##################### Grafana Configuration Defaults #####################
#
# Do not modify this file in grafana installs
#
# possible values : production, development
app_mode = production
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
instance_name = ${HOSTNAME}
#################################### Paths ###############################
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
data = /var/lib/grafana
# Temporary files in `data` directory older than given duration will be removed
temp_data_lifetime = 24h
# Directory where grafana can store logs
logs = /var/log/grafana
# Directory where grafana will automatically scan and look for plugins
plugins = /var/lib/grafana/plugins
# folder that contains provisioning config files that grafana will apply on startup and while running.
provisioning = /etc/grafana/provisioning
#################################### Server ##############################
[server]
# Protocol (http, https, h2, socket)
protocol = http
# The ip address to bind to, empty will bind to all interfaces
http_addr =
# The http port to use
http_port = 3000
# The public facing domain name used to access grafana from a browser
domain = grafana.pyrocufflink.blue
# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
enforce_domain = false
# The full public facing url
root_url = %(protocol)s://%(domain)s:%(http_port)s/
# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
serve_from_sub_path = false
# Log web requests
router_logging = false
# the path relative working path
static_root_path = public
# enable gzip
enable_gzip = false
# https certs & key file
cert_file =
cert_key =
# Unix socket path
socket = /tmp/grafana.sock
#################################### Database ############################
[database]
# You can configure the database connection by specifying type, host, name, user and password
# as separate properties or as on string using the url property.
# Either "mysql", "postgres" or "sqlite3", it's your choice
type = sqlite3
host = 127.0.0.1:3306
name = grafana
user = root
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
password =
# Use either URL or the previous fields to configure the database
# Example: mysql://user:secret@host:port/database
url =
# Max idle conn setting default is 2
max_idle_conn = 2
# Max conn setting default is 0 (mean not set)
max_open_conn =
# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
conn_max_lifetime = 14400
# Set to true to log the sql calls and execution times.
log_queries =
# For "postgres", use either "disable", "require" or "verify-full"
# For "mysql", use either "true", "false", or "skip-verify".
ssl_mode = disable
ca_cert_path =
client_key_path =
client_cert_path =
server_cert_name =
# For "sqlite3" only, path relative to data_path setting
path = grafana.db
# For "sqlite3" only. cache mode setting used for connecting to the database
cache_mode = private
#################################### Cache server #############################
[remote_cache]
# Either "redis", "memcached" or "database" default is "database"
type = database
# cache connectionstring options
# database: will use Grafana primary database.
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'.
# memcache: 127.0.0.1:11211
connstr =
#################################### Data proxy ###########################
[dataproxy]
# This enables data proxy logging, default is false
logging = false
# How long the data proxy waits before timing out, default is 30 seconds.
# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set.
timeout = 30
# How many seconds the data proxy waits before sending a keepalive request.
keep_alive_seconds = 30
# How many seconds the data proxy waits for a successful TLS Handshake before timing out.
tls_handshake_timeout_seconds = 10
# How many seconds the data proxy will wait for a server's first response headers after
# fully writing the request headers if the request has an "Expect: 100-continue"
# header. A value of 0 will result in the body being sent immediately, without
# waiting for the server to approve.
expect_continue_timeout_seconds = 1
# The maximum number of idle connections that Grafana will keep alive.
max_idle_connections = 100
# How many seconds the data proxy keeps an idle connection open before timing out.
idle_conn_timeout_seconds = 90
# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request.
send_user_header = true
#################################### Analytics ###########################
[analytics]
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
reporting_enabled = false
# Set to false to disable all checks to https://grafana.com
# for new versions (grafana itself and plugins), check is used
# in some UI views to notify that grafana or plugin update exists
# This option does not cause any auto updates, nor send any information
# only a GET request to https://grafana.com to get latest versions
check_for_updates = false
# Google Analytics universal tracking code, only enabled if you specify an id here
google_analytics_ua_id =
# Google Tag Manager ID, only enabled if you specify an id here
google_tag_manager_id =
#################################### Security ############################
[security]
# disable creation of admin user on first start of grafana
disable_initial_admin_creation = false
# default admin user, created on startup
admin_user = admin
# default admin password, can be changed before first start of grafana, or in profile settings
admin_password = admin
# used for signing
secret_key = SW2YcwTIb9zpOOhoPsMm
# disable gravatar profile images
disable_gravatar = false
# data source proxy whitelist (ip_or_domain:port separated by spaces)
data_source_proxy_whitelist =
# disable protection against brute force login attempts
disable_brute_force_login_protection = false
# set to true if you host Grafana behind HTTPS. default is false.
cookie_secure = false
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
cookie_samesite = lax
# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
allow_embedding = false
# Set to true if you want to enable http strict transport security (HSTS) response header.
# This is only sent when HTTPS is enabled in this configuration.
# HSTS tells browsers that the site should only be accessed using HTTPS.
strict_transport_security = false
# Sets how long a browser should cache HSTS. Only applied if strict_transport_security is enabled.
strict_transport_security_max_age_seconds = 86400
# Set to true if to enable HSTS preloading option. Only applied if strict_transport_security is enabled.
strict_transport_security_preload = false
# Set to true if to enable the HSTS includeSubDomains option. Only applied if strict_transport_security is enabled.
strict_transport_security_subdomains = false
# Set to true to enable the X-Content-Type-Options response header.
# The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised
# in the Content-Type headers should not be changed and be followed.
x_content_type_options = true
# Set to true to enable the X-XSS-Protection header, which tells browsers to stop pages from loading
# when they detect reflected cross-site scripting (XSS) attacks.
x_xss_protection = true
#################################### Snapshots ###########################
[snapshots]
# snapshot sharing options
external_enabled = false
external_snapshot_url = https://snapshots-origin.raintank.io
external_snapshot_name = Publish to snapshot.raintank.io
# Set to true to enable this Grafana instance act as an external snapshot server and allow unauthenticated requests for
# creating and deleting snapshots.
public_mode = false
# remove expired snapshot
snapshot_remove_expired = true
#################################### Dashboards ##################
[dashboards]
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
versions_to_keep = 20
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
min_refresh_interval = 1s
# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
default_home_dashboard_path =
#################################### Users ###############################
[users]
# disable user signup / registration
allow_sign_up = false
# Allow non admin users to create organizations
allow_org_create = false
# Set to true to automatically assign new users to the default organization (id 1)
auto_assign_org = true
# Set this value to automatically add new users to the provided organization (if auto_assign_org above is set to true)
auto_assign_org_id = 1
# Default role new users will be automatically assigned (if auto_assign_org above is set to true)
auto_assign_org_role = Viewer
# Require email validation before sign up completes
verify_email_enabled = false
# Background text for the user field on the login page
login_hint = email or username
password_hint = password
# Default UI theme ("dark" or "light")
default_theme = dark
# External user management
external_manage_link_url =
external_manage_link_name =
external_manage_info =
# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
viewers_can_edit = false
# Editors can administrate dashboard, folders and teams they create
editors_can_admin = false
# The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes).
user_invite_max_lifetime_duration = 24h
[auth]
# Login cookie name
login_cookie_name = grafana_session
# The maximum lifetime (duration) an authenticated user can be inactive before being required to login at next visit. Default is 7 days (7d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month). The lifetime resets at each successful token rotation (token_rotation_interval_minutes).
login_maximum_inactive_lifetime_duration =
# The maximum lifetime (duration) an authenticated user can be logged in since login time before being required to login. Default is 30 days (30d). This setting should be expressed as a duration, e.g. 5m (minutes), 6h (hours), 10d (days), 2w (weeks), 1M (month).
login_maximum_lifetime_duration =
# How often should auth tokens be rotated for authenticated users when being active. The default is each 10 minutes.
token_rotation_interval_minutes = 10
# Set to true to disable (hide) the login form, useful if you use OAuth
disable_login_form = false
# Set to true to disable the signout link in the side menu. useful if you use auth.proxy
disable_signout_menu = false
# URL to redirect the user to after sign out
signout_redirect_url =
# Set to true to attempt login with OAuth automatically, skipping the login screen.
# This setting is ignored if multiple OAuth providers are configured.
oauth_auto_login = false
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
oauth_state_cookie_max_age = 600
# limit of api_key seconds to live before expiration
api_key_max_seconds_to_live = -1
# Set to true to enable SigV4 authentication option for HTTP-based datasources
sigv4_auth_enabled = false
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
enabled = true
# specify organization name that should be used for unauthenticated users
org_name = Main Org.
# specify role for unauthenticated users
org_role = Viewer
# mask the Grafana version number for unauthenticated users
hide_version = false
#################################### GitHub Auth #########################
[auth.github]
enabled = false
allow_sign_up = true
client_id = some_id
client_secret =
scopes = user:email,read:org
auth_url = https://github.com/login/oauth/authorize
token_url = https://github.com/login/oauth/access_token
api_url = https://api.github.com/user
allowed_domains =
team_ids =
allowed_organizations =
#################################### GitLab Auth #########################
[auth.gitlab]
enabled = false
allow_sign_up = true
client_id = some_id
client_secret =
scopes = api
auth_url = https://gitlab.com/oauth/authorize
token_url = https://gitlab.com/oauth/token
api_url = https://gitlab.com/api/v4
allowed_domains =
allowed_groups =
#################################### Google Auth #########################
[auth.google]
enabled = false
allow_sign_up = true
client_id = some_client_id
client_secret =
scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
auth_url = https://accounts.google.com/o/oauth2/auth
token_url = https://accounts.google.com/o/oauth2/token
api_url = https://www.googleapis.com/oauth2/v1/userinfo
allowed_domains =
hosted_domain =
#################################### Grafana.com Auth ####################
# legacy key names (so they work in env variables)
[auth.grafananet]
enabled = false
allow_sign_up = true
client_id = some_id
client_secret =
scopes = user:email
allowed_organizations =
[auth.grafana_com]
enabled = false
allow_sign_up = true
client_id = some_id
client_secret =
scopes = user:email
allowed_organizations =
#################################### Azure AD OAuth #######################
[auth.azuread]
name = Azure AD
enabled = false
allow_sign_up = true
client_id = some_client_id
client_secret =
scopes = openid email profile
auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
allowed_domains =
allowed_groups =
#################################### Okta OAuth #######################
[auth.okta]
name = Okta
enabled = false
allow_sign_up = true
client_id = some_id
client_secret =
scopes = openid profile email groups
auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
token_url = https://<tenant-id>.okta.com/oauth2/v1/token
api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
allowed_domains =
allowed_groups =
role_attribute_path =
#################################### Generic OAuth #######################
[auth.generic_oauth]
name = OAuth
enabled = false
allow_sign_up = true
client_id = some_id
client_secret =
scopes = user:email
email_attribute_name = email:primary
email_attribute_path =
login_attribute_path =
role_attribute_path =
id_token_attribute_name =
auth_url =
token_url =
api_url =
allowed_domains =
team_ids =
allowed_organizations =
tls_skip_verify_insecure = false
tls_client_cert =
tls_client_key =
tls_client_ca =
#################################### Basic Auth ##########################
[auth.basic]
enabled = true
#################################### Auth Proxy ##########################
[auth.proxy]
enabled = false
header_name = X-WEBAUTH-USER
header_property = username
auto_sign_up = true
# Deprecated, use sync_ttl instead
ldap_sync_ttl = 60
sync_ttl = 60
whitelist =
headers =
enable_login_token = false
#################################### Auth LDAP ###########################
[auth.ldap]
enabled = true
config_file = /etc/grafana/ldap.toml
allow_sign_up = false
# LDAP backround sync (Enterprise only)
# At 1 am every day
sync_cron = "0 0 1 * * *"
active_sync_enabled = false
#################################### SMTP / Emailing #####################
[smtp]
enabled = false
host = localhost:25
user =
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
password =
cert_file =
key_file =
skip_verify = false
from_address = admin@grafana.localhost
from_name = Grafana
ehlo_identity =
startTLS_policy =
[emails]
welcome_email_on_sign_up = false
templates_pattern = emails/*.html
#################################### Logging ##########################
[log]
# Either "console", "file", "syslog". Default is console and file
# Use space to separate multiple modes, e.g. "console file"
mode = console
# Either "debug", "info", "warn", "error", "critical", default is "info"
level = info
# optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
filters =
# For "console" mode only
[log.console]
level =
# log line format, valid options are text, console and json
format = console
# For "file" mode only
[log.file]
level =
# log line format, valid options are text, console and json
format = text
# This enables automated log rotate(switch of following options), default is true
log_rotate = true
# Max line number of single file, default is 1000000
max_lines = 1000000
# Max size shift of single file, default is 28 means 1 << 28, 256MB
max_size_shift = 28
# Segment log daily, default is true
daily_rotate = true
# Expired days of log file(delete after max days), default is 7
max_days = 7
[log.syslog]
level =
# log line format, valid options are text, console and json
format = text
# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
network =
address =
# Syslog facility. user, daemon and local0 through local7 are valid.
facility =
# Syslog tag. By default, the process' argv[0] is used.
tag =
#################################### Usage Quotas ########################
[quota]
enabled = false
#### set quotas to -1 to make unlimited. ####
# limit number of users per Org.
org_user = 10
# limit number of dashboards per Org.
org_dashboard = 100
# limit number of data_sources per Org.
org_data_source = 10
# limit number of api_keys per Org.
org_api_key = 10
# limit number of orgs a user can create.
user_org = 10
# Global limit of users.
global_user = -1
# global limit of orgs.
global_org = -1
# global limit of dashboards
global_dashboard = -1
# global limit of api_keys
global_api_key = -1
# global limit on number of logged in users.
global_session = -1
#################################### Annotations #########################
[annotations.dashboard]
# Dashboard annotations means that annotations are associated with the dashboard they are created on.
# Configures how long dashboard annotations are stored. Default is 0, which keeps them forever.
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
max_age =
# Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations.
max_annotations_to_keep =
[annotations.api]
# API annotations means that the annotations have been created using the API without any
# association with a dashboard.
# Configures how long Grafana stores API annotations. Default is 0, which keeps them forever.
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
max_age =
# Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations.
max_annotations_to_keep =
#################################### Explore #############################
[explore]
# Enable the Explore section
enabled = true
#################################### Internal Grafana Metrics ############
# Metrics available at HTTP API Url /metrics
[metrics]
enabled = true
interval_seconds = 10
# Disable total stats (stat_totals_*) metrics to be generated
disable_total_stats = false
#If both are set, basic auth will be required for the metrics endpoint.
basic_auth_username =
basic_auth_password =
# Metrics environment info adds dimensions to the `grafana_environment_info` metric, which
# can expose more information about the Grafana instance.
[metrics.environment_info]
#exampleLabel1 = exampleValue1
#exampleLabel2 = exampleValue2
# Send internal Grafana metrics to graphite
[metrics.graphite]
# Enable by setting the address setting (ex localhost:2003)
address =
prefix = prod.grafana.%(instance_name)s.
#################################### Grafana.com integration ##########################
[grafana_net]
url = https://grafana.com
[grafana_com]
url = https://grafana.com
#################################### Distributed tracing ############
[tracing.jaeger]
# jaeger destination (ex localhost:6831)
address =
# tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
always_included_tag =
# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
sampler_type = const
# jaeger samplerconfig param
# for "const" sampler, 0 or 1 for always false/true respectively
# for "probabilistic" sampler, a probability between 0 and 1
# for "rateLimiting" sampler, the number of spans per second
# for "remote" sampler, param is the same as for "probabilistic"
# and indicates the initial sampling rate before the actual one
# is received from the mothership
sampler_param = 1
# sampling_server_url is the URL of a sampling manager providing a sampling strategy.
sampling_server_url =
# Whether or not to use Zipkin span propagation (x-b3- HTTP headers).
zipkin_propagation = false
# Setting this to true disables shared RPC spans.
# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
disable_shared_zipkin_spans = false
#################################### External Image Storage ##############
[external_image_storage]
# Used for uploading images to public servers so they can be included in slack/email messages.
# You can choose between (s3, webdav, gcs, azure_blob, local)
provider =
[external_image_storage.s3]
endpoint =
path_style_access =
bucket_url =
bucket =
region =
path =
access_key =
secret_key =
[external_image_storage.webdav]
url =
username =
password =
public_url =
[external_image_storage.gcs]
key_file =
bucket =
path =
enable_signed_urls = false
signed_url_expiration =
[external_image_storage.azure_blob]
account_name =
account_key =
container_name =
[external_image_storage.local]
# does not require any configuration
[rendering]
# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
server_url =
# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
callback_url =
# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
# which this setting can help protect against by only allowing a certain amount of concurrent requests.
concurrent_render_request_limit = 30
[panels]
# here for to support old env variables, can remove after a few months
enable_alpha = false
disable_sanitize_html = false
[plugins]
enable_alpha = false
app_tls_skip_verify_insecure = false
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
allow_loading_unsigned_plugins = pcp-redis-datasource
marketplace_url = https://grafana.com/grafana/plugins/
#################################### Grafana Image Renderer Plugin ##########################
[plugin.grafana-image-renderer]
# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
# See ICUs metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
# timezone IDs. Fallbacks to TZ environment variable if not set.
rendering_timezone =
# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
rendering_language =
# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
rendering_viewport_device_scale_factor =
# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
# the security risk it's not recommended to ignore HTTPS errors.
rendering_ignore_https_errors =
# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
# only capture and log error messages. When enabled, debug messages are captured and logged as well.
# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
# [log].filter = rendering:debug.
rendering_verbose_logging =
# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
# Default is false. This can be useful to enable (true) when troubleshooting.
rendering_dumpio =
# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
rendering_args =
# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
# compatible with the plugin.
rendering_chrome_bin =
# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
rendering_mode =
# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
# and will cluster using browser instances.
# Mode 'context' will cluster using incognito pages.
rendering_clustering_mode =
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
rendering_clustering_max_concurrency =
# Limit the maximum viewport width, height and device scale factor that can be requested.
rendering_viewport_max_width =
rendering_viewport_max_height =
rendering_viewport_max_device_scale_factor =
# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
# a port not in use.
grpc_host =
grpc_port =
[enterprise]
license_path =
[feature_toggles]
# enable features, separated by spaces
enable =
[date_formats]
# For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/
# Default system date format used in time range picker and other places where full time is displayed
full_date = YYYY-MM-DD HH:mm:ss
# Used by graph and other places where we only show small intervals
interval_second = HH:mm:ss
interval_minute = HH:mm
interval_hour = MM/DD HH:mm
interval_day = MM/DD
interval_month = YYYY-MM
interval_year = YYYY
# Experimental feature
use_browser_locale = false
# Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc.
default_timezone = browser

106
grafana/grafana.yaml Normal file
View File

@ -0,0 +1,106 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: grafana
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
spec:
ports:
- port: 3000
name: grafana
selector:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: grafana
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
spec:
serviceName: grafana
selector:
matchLabels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
template:
metadata:
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
spec:
containers:
- name: grafana
image: docker.io/grafana/grafana:10.2.3
ports:
- containerPort: 3000
name: http
readinessProbe: &probe
httpGet:
port: http
path: /api/health
periodSeconds: 60
startupProbe:
<<: *probe
periodSeconds: 1
successThreshold: 1
failureThreshold: 30
timeoutSeconds: 1
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /etc/grafana
name: config
readOnly: true
- mountPath: /etc/grafana/provisioning/datasources
name: datasources
readOnly: true
- mountPath: /tmp
name: tmp
- mountPath: /run/secrets/grafana
name: secrets
readOnly: true
- mountPath: /var/lib/grafana
name: grafana
subPath: data
securityContext:
fsGroup: 472
runAsNonRoot: true
volumes:
- name: config
configMap:
name: grafana
- name: datasources
configMap:
name: datasources
optional: true
- name: grafana
persistentVolumeClaim:
claimName: grafana
- name: tmp
emptyDir:
medium: Memory
- name: secrets
secret:
secretName: grafana

19
grafana/ingress.yaml Normal file
View File

@ -0,0 +1,19 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
spec:
rules:
- host: grafana.pyrocufflink.blue
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grafana
port:
name: grafana

View File

@ -0,0 +1,61 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: grafana
labels:
- pairs:
app.kubernetes.io/instance: grafana
includeSelectors: true
- pairs:
app.kubernetes.io/part-of: grafana
includeSelectors: false
resources:
- namespace.yaml
- grafana.yaml
- ingress.yaml
- secrets.yaml
- loki-cert.yaml
- ../dch-root-ca
configMapGenerator:
- name: grafana
files:
- grafana.ini
- ldap.toml
- name: datasources
files:
- datasources/loki.yml
- datasources/victoria-logs.yml
patches:
- patch: |-
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: grafana
spec:
template:
spec:
containers:
- name: grafana
volumeMounts:
- mountPath: /run/dch-ca
name: dch-ca
readOnly: true
- mountPath: /run/secrets/du5t1n.me/loki
name: loki-client-cert
readOnly: true
volumes:
- name: dch-ca
configMap:
name: dch-root-ca
- name: loki-client-cert
secret:
secretName: loki-client-cert
images:
- name: docker.io/grafana/grafana
newTag: 11.5.5

55
grafana/ldap.toml Normal file
View File

@ -0,0 +1,55 @@
# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
# [log]
# filters = ldap:debug
[[servers]]
# Ldap server host (specify multiple hosts space separated)
host = "pyrocufflink.blue"
# Default port is 389 or 636 if use_ssl = true
port = 389
# Set to true if ldap server supports TLS
use_ssl = true
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
start_tls = true
# set to true if you want to skip ssl cert validation
ssl_skip_verify = false
# set to the path to your root CA certificate or leave unset to use system defaults
root_ca_cert = "/run/dch-ca/dch-root-ca.crt"
# Authentication against LDAP servers requiring client certificates
# client_cert = "/path/to/client.crt"
# client_key = "/path/to/client.key"
# Search user bind dn
bind_dn = "CN=svc.grafana,CN=Users,DC=pyrocufflink,DC=blue"
# Search user bind password
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
bind_password = '$__file{/run/secrets/grafana/ldap.password}'
# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"
search_filter = "(sAMAccountName=%s)"
# An array of base dns to search through
search_base_dns = ["DC=pyrocufflink,DC=blue"]
## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
## Please check grafana LDAP docs for examples
# group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
# group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]
# group_search_filter_user_attribute = "uid"
# Specify names of the ldap attributes your ldap uses
[servers.attributes]
name = "givenName"
surname = "sn"
username = "sAMAccountName"
member_of = "memberOf"
email = "mail"
# Map ldap groups to grafana org roles
[[servers.group_mappings]]
group_dn = "CN=Grafana Admins,CN=Users,DC=pyrocufflink,DC=blue"
org_role = "Admin"
grafana_admin = true
[[servers.group_mappings]]
group_dn = "*"
org_role = "Viewer"

12
grafana/loki-cert.yaml Normal file
View File

@ -0,0 +1,12 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: loki-client-cert
spec:
commonName: grafana
privateKey:
algorithm: Ed25519
secretName: loki-client-cert
issuerRef:
name: loki-ca
kind: ClusterIssuer

6
grafana/namespace.yaml Normal file
View File

@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: grafana
labels:
app.kubernetes.io/name: grafana

18
grafana/secrets.yaml Normal file
View File

@ -0,0 +1,18 @@
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: grafana
namespace: grafana
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana
spec:
encryptedData:
ldap.password: AgAPlAsgFK6eKUGeHJymXHgSXbXaKm8uoFwmSgGV0RnXdzhQwKgd67XlXjuN3UHQL6LL6kAz44qiN7C4E21ZZ+WgFfs7CrLGAh1mQ713OH5W9j9CdpH5QdxDdqgmOq2ZBleijKb/XWZdMW6kZZLK03SzjZk80FHR7YaWKnJOsvVj6QQS5ZAamp0sv4wnQnhK86uZvn6cbtIgjXU/bhGiibCh1Gj/c/2rr0aPHAD3NZy6HuLH43SJN2LAvVwL6BQYoxLJ7Af680+tdWnqoYNNHexKphUWvQlfEXYnvS1JXPBynHsFHxBD2xlU/sFnvqJPN6YCu9LXbzGGacZreJX5giKYt5mAuotpvsF/59QzVEW5U6l0f0felOPSeaBvfl8mHkq2ude5SuLedtgaZKMTaI4QM6DcPmjlUoZU5sizDP9fdsw2iuhyEV5tJprmm2p9tuzFXsV/NY7L79m6iJMh0VTfpbglkec8R7f1im04sbBDR6v/Quw3U3R1erndzymZIGzjG7qKwnGzAvNhTTW+9FOLjCBVhE1Jk6PfX0efAkL9UiB3Vo5qpJw535rZa4KP9KfkGiJE8RhsdIqRMnMo2wPzRkiJF+eb+P3v0eIkAeBpPdioK3MI02d+KS+vgGu9cuVeq1jCONkfIfp3EYnxGsu3ZPWyZRzbTwS6m4XV6Ov4NMq5YpjjpnCnMHq3nFg+H14WLqs68TIgNeWwhRJyqhnvpWA+/A6GC6PHzeELpL3xAg==
template:
metadata:
name: grafana
namespace: grafana
labels:
app.kubernetes.io/name: grafana
app.kubernetes.io/component: grafana

View File

@ -1 +1,2 @@
mosquitto.passwd mosquitto.passwd
secrets.yaml.in

Some files were not shown because too many files have changed in this diff Show More