diff --git a/chart/.helmignore b/chart/.helmignore new file mode 100644 index 0000000..c47a352 --- /dev/null +++ b/chart/.helmignore @@ -0,0 +1,34 @@ +# A helm chart's templates and default values can be packaged into a .tgz file. +# When doing that, not everything should be bundled into the .tgz file. This +# file describes what to not bundle. +# +# Manually added by us +# -------------------- +# + +# Boilerplate .helmignore from `helm create mastodon` +# --------------------------------------------------- +# +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/chart/Chart.yaml b/chart/Chart.yaml new file mode 100644 index 0000000..1fb2e5c --- /dev/null +++ b/chart/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +name: fediblockhole +description: FediBlockHole is a tool for keeping a Mastodon instance blocklist synchronised with remote lists. + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 1.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +appVersion: 0.4.2 diff --git a/chart/fediblockhole.conf.toml b/chart/fediblockhole.conf.toml new file mode 100644 index 0000000..e377e97 --- /dev/null +++ b/chart/fediblockhole.conf.toml @@ -0,0 +1,67 @@ +# List of instances to read blocklists from. +# If the instance makes its blocklist public, no authorization token is needed. +# Otherwise, `token` is a Bearer token authorised to read domain_blocks. +# If `admin` = True, use the more detailed admin API, which requires a token with a +# higher level of authorization. +# If `import_fields` are provided, only import these fields from the instance. +# Overrides the global `import_fields` setting. +blocklist_instance_sources = [ + # { domain = 'public.blocklist'}, # an instance with a public list of domain_blocks + # { domain = 'jorts.horse', token = '' }, # user accessible block list + # { domain = 'eigenmagic.net', token = '', admin = true }, # admin access required +] + +# List of URLs to read csv blocklists from +# Format tells the parser which format to use when parsing the blocklist +# max_severity tells the parser to override any severities that are higher than this value +# import_fields tells the parser to only import that set of fields from a specific source +blocklist_url_sources = [ + # { url = 'file:///path/to/fediblockhole/samples/demo-blocklist-01.csv', format = 'csv' }, + { url = 'https://raw.githubusercontent.com/eigenmagic/fediblockhole/main/samples/demo-blocklist-01.csv', format = 'csv' }, + +] + +## These global allowlists override blocks from blocklists +# These are the same format and structure as blocklists, but they take precedence +allowlist_url_sources = [ + { url = 'https://raw.githubusercontent.com/eigenmagic/fediblockhole/main/samples/demo-allowlist-01.csv', format = 'csv' }, + { url = 'https://raw.githubusercontent.com/eigenmagic/fediblockhole/main/samples/demo-allowlist-02.csv', format = 'csv' }, +] + +# List of instances to write blocklist to +blocklist_instance_destinations = [ + # { domain = 'eigenmagic.net', token = '', max_followed_severity = 'silence'}, +] + +## Store a local copy of the remote blocklists after we fetch them +#save_intermediate = true + +## Directory to store the local blocklist copies +# savedir = '/tmp' + +## File to save the fully merged blocklist into +# blocklist_savefile = '/tmp/merged_blocklist.csv' + +## Don't push blocklist to instances, even if they're defined above +# no_push_instance = false + +## Don't fetch blocklists from URLs, even if they're defined above +# no_fetch_url = false + +## Don't fetch blocklists from instances, even if they're defined above +# no_fetch_instance = false + +## Set the mergeplan to use when dealing with overlaps between blocklists +# The default 'max' mergeplan will use the harshest severity block found for a domain. +# The 'min' mergeplan will use the lightest severity block found for a domain. +# mergeplan = 'max' + +## Set which fields we import +## 'domain' and 'severity' are always imported, these are additional +## +import_fields = ['public_comment', 'reject_media', 'reject_reports', 'obfuscate'] + +## Set which fields we export +## 'domain' and 'severity' are always exported, these are additional +## +export_fields = ['public_comment'] diff --git a/chart/templates/_helpers.tpl b/chart/templates/_helpers.tpl new file mode 100644 index 0000000..78e6610 --- /dev/null +++ b/chart/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "fediblockhole.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "fediblockhole.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "fediblockhole.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "fediblockhole.labels" -}} +helm.sh/chart: {{ include "fediblockhole.chart" . }} +{{ include "fediblockhole.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "fediblockhole.selectorLabels" -}} +app.kubernetes.io/name: {{ include "fediblockhole.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Rolling pod annotations +*/}} +{{- define "fediblockhole.rollingPodAnnotations" -}} +rollme: {{ .Release.Revision | quote }} +checksum/config-configmap: {{ include ( print $.Template.BasePath "/configmap-conf-toml.yaml" ) . | sha256sum | quote }} +{{- end }} + +{{/* +Create the default conf file path and filename +*/}} +{{- define "fediblockhole.conf_file_path" -}} +{{- default "/etc/default/" .Values.fediblockhole.conf_file.path }} +{{- end }} +{{- define "fediblockhole.conf_file_filename" -}} +{{- default "fediblockhole.conf.toml" .Values.fediblockhole.conf_file.filename }} +{{- end }} diff --git a/chart/templates/configmap-conf-toml.yaml b/chart/templates/configmap-conf-toml.yaml new file mode 100644 index 0000000..f320b67 --- /dev/null +++ b/chart/templates/configmap-conf-toml.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "fediblockhole.fullname" . }}-conf-toml + labels: + {{- include "fediblockhole.labels" . | nindent 4 }} +data: + {{ (.Files.Glob "fediblockhole.conf.toml").AsConfig | nindent 4 }} diff --git a/chart/templates/cronjob-fediblock-sync.yaml b/chart/templates/cronjob-fediblock-sync.yaml new file mode 100644 index 0000000..f738222 --- /dev/null +++ b/chart/templates/cronjob-fediblock-sync.yaml @@ -0,0 +1,68 @@ +{{ if .Values.fediblockhole.cron.sync.enabled -}} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ include "fediblockhole.fullname" . }}-sync + labels: + {{- include "fediblockhole.labels" . | nindent 4 }} +spec: + schedule: {{ .Values.fediblockhole.cron.sync.schedule }} + failedJobsHistoryLimit: {{ .Values.fediblockhole.cron.sync.failedJobsHistoryLimit }} + successfulJobsHistoryLimit: {{ .Values.fediblockhole.cron.sync.successfulJobsHistoryLimit }} + jobTemplate: + spec: + template: + metadata: + name: {{ include "fediblockhole.fullname" . }}-sync + {{- with .Values.jobAnnotations }} + annotations: + {{- toYaml . | nindent 12 }} + {{- end }} + spec: + restartPolicy: OnFailure + containers: + - name: {{ include "fediblockhole.fullname" . }}-sync + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - fediblock-sync + - -c + - "{{- include "fediblockhole.conf_file_path" . -}}{{- include "fediblockhole.conf_file_filename" . -}}" + volumeMounts: + - name: config + mountPath: "{{- include "fediblockhole.conf_file_path" . -}}{{- include "fediblockhole.conf_file_filename" . -}}" + subPath: "{{- include "fediblockhole.conf_file_filename" . -}}" + {{ if .Values.fediblockhole.allow_file.filename }} + - name: allowfile + mountPath: "{{- include "fediblockhole.conf_file_path" . -}}{{- .Values.fediblockhole.allow_file.filename -}}" + subPath: "{{- .Values.fediblockhole.allow_file.filename -}}" + {{ end }} + {{ if .Values.fediblockhole.block_file.filename }} + - name: blockfile + mountPath: "{{- include "fediblockhole.conf_file_path" . -}}{{- .Values.fediblockhole.block_file.filename -}}" + subPath: "{{- .Values.fediblockhole.block_file.filename -}}" + {{ end }} + volumes: + - name: config + configMap: + name: {{ include "fediblockhole.fullname" . }}-conf-toml + items: + - key: {{ include "fediblockhole.conf_file_filename" . | quote }} + path: {{ include "fediblockhole.conf_file_filename" . | quote }} + {{ if .Values.fediblockhole.allow_file.filename }} + - name: allowfile + configMap: + name: {{ include "fediblockhole.fullname" . }}-allow-csv + items: + - key: {{ .Values.fediblockhole.allow_file.filename | quote }} + path: {{ .Values.fediblockhole.allow_file.filename | quote }} + {{ end }} + {{ if .Values.fediblockhole.block_file.filename }} + - name: blockfile + configMap: + name: {{ include "fediblockhole.fullname" . }}-block-csv + items: + - key: {{ .Values.fediblockhole.block_file.filename | quote }} + path: {{ .Values.fediblockhole.block_file.filename | quote }} + {{ end }} +{{- end }} diff --git a/chart/values.yaml b/chart/values.yaml new file mode 100644 index 0000000..74643c1 --- /dev/null +++ b/chart/values.yaml @@ -0,0 +1,77 @@ +image: + repository: ghcr.io/cunningpike/fediblockhole + # https://github.com/cunningpike/fediblockhole/pkgs/container/fediblockhole/versions + # + # alternatively, use `latest` for the latest release or `edge` for the image + # built from the most recent commit + # + # tag: latest + tag: "" + # use `Always` when using `latest` tag + pullPolicy: IfNotPresent + +fediblockhole: + # location of the configuration file. Default is /etc/default/fediblockhole.conf.toml + conf_file: + path: "" + filename: "" + # Location of a local allowlist file. It is recommended that this file should at a + # minimum contain the web_domain of your own instance. + allow_file: + # Optionally, set the name of the file. This should match the data key in the + # associated ConfigMap + filename: "" + # Location of a local blocklist file. + block_file: + # Optionally, set the name of the file. This should match the data key in the + # associated ConfigMap + filename: "" + cron: + # -- run `fediblock-sync` every hour + sync: + # @ignored + enabled: false + # @ignored + schedule: "0 * * * *" + failedJobsHistoryLimit: 1 + successfulJobsHistoryLimit: 3 + +# if you manually change the UID/GID environment variables, ensure these values +# match: +podSecurityContext: + runAsUser: 991 + runAsGroup: 991 + fsGroup: 991 + +# @ignored +securityContext: {} + +# -- Kubernetes manages pods for jobs and pods for deployments differently, so you might +# need to apply different annotations to the two different sets of pods. The annotations +# set with podAnnotations will be added to all deployment-managed pods. +podAnnotations: {} + +# -- The annotations set with jobAnnotations will be added to all job pods. +jobAnnotations: {} + +# -- Default resources for all Deployments and jobs unless overwritten +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +# @ignored +nodeSelector: {} + +# @ignored +tolerations: [] + +# -- Affinity for all pods unless overwritten +affinity: {} diff --git a/container/.dockerignore b/container/.dockerignore new file mode 100644 index 0000000..a78e7f7 --- /dev/null +++ b/container/.dockerignore @@ -0,0 +1,6 @@ +Dockerfile +#README.md +*.pyc +*.pyo +*.pyd +__pycache__ diff --git a/container/Dockerfile b/container/Dockerfile new file mode 100644 index 0000000..3659567 --- /dev/null +++ b/container/Dockerfile @@ -0,0 +1,14 @@ +# Use the official lightweight Python image. +# https://hub.docker.com/_/python +FROM python:slim + +# Copy local code to the container image. +ENV APP_HOME /app +WORKDIR $APP_HOME + +# Install production dependencies. +RUN pip install fediblockhole + +USER 1001 +# Set the command on start to fediblock-sync. +ENTRYPOINT ["fediblock-sync"]