weebo-forgejo

Concepts

The few ideas behind the operator, and the words the rest of the docs use.

How it works

  you / GitOps ──apply──▶  Kubernetes API  ──watch──▶  weebo-forgejo  ──REST API──▶  Forgejo
                            (custom resources)          (operator)       (admin token)
                                    ▲                        │
                                    └──── status, events ────┘
                                                             └──▶ Secrets / Vault

You describe what Forgejo should contain as Kubernetes resources. The operator watches them, compares each one with Forgejo, sends only the changes needed, and writes the outcome back on the resource's status. Credentials it generates are written to Secrets or Vault.

Vocabulary

TermMeaning
CR (custom resource)One YAML object of a kind this operator adds, such as a ForgejoRepository. Each CR stands for one object in Forgejo.
CRDThe definition of a kind (its fields and their types). The chart installs them; see the CRD reference.
ReconcileOne pass where the operator compares a CR with Forgejo and fixes the difference. It runs when the CR changes, when something it refers to changes, and periodically.
DriftA difference that appeared in Forgejo after the fact, such as a setting changed by hand in the UI. The next reconcile undoes it.
AuthoritativeA field or list the operator enforces completely: for memberRefs on a team, anyone not listed is removed.
Ref (organizationRef, userRef…)A pointer to another CR by its Kubernetes name — of the same namespace, or of another one (namespace) when the operator allows it and the target shares itself — or to a Forgejo object no CR manages, by its Forgejo name (remoteName).
Management policyManage (the default) lets the operator create and edit the object. Observe only looks it up so other CRs can refer to it, without ever changing it.
Deletion policyWhat happens in Forgejo when the CR is deleted: Orphan keeps the object, Delete removes it.
FinalizerA marker Kubernetes keeps on a CR until the operator has finished cleaning up, so a deletion is never half done.
Secret targetsWhere a generated credential is written: one or more Kubernetes Secrets and/or Vault paths. See Credentials.
Admission webhookA check the API server runs before accepting a CR. It enforces the allow-list at kubectl apply time.
Disruptive updateA change Forgejo can only do by recreating the object, or one that breaks its consumers. It's refused unless you opt in with an annotation; see Disruptive changes.

The kinds

Only the instance and the allow-list are cluster-scoped, governed by Kubernetes RBAC alone. Every other kind is namespaced: it belongs to a team, and — when bound to a shared ForgejoInstance — is also governed by the allow-list. Every kind has a short name for kubectl get.

KindShort nameScopeStands for
ForgejoInstancefjiClusterThe connection to a Forgejo
ForgejoLocalInstancefjliNamespacedA namespace's own connection to a Forgejo
ForgejoUserfjuserNamespacedA user or bot account
ForgejoUserKeyfjukeyNamespacedAn SSH key on a user
ForgejoOrganizationfjorgNamespacedAn organization
ForgejoTeamfjteamNamespacedA team in an organization, and its members
ForgejoNamespacePolicyfjnpClusterAllow-list rules for the namespaced kinds
ForgejoRepositoryfjrepoNamespacedA repository, its settings, team access and branch protection
ForgejoWebhookfjhookNamespacedA repository or organization webhook
ForgejoDeployKeyfjdkeyNamespacedAn SSH deploy key on a repository
ForgejoOAuth2ApplicationfjoauthNamespacedAn OAuth2 client, delivered to a Secret
ForgejoAccessTokenfjtokenNamespacedAn API token, delivered to a Secret

Status

Every CR reports the same way: a Ready condition with a reason (a stable code such as Reconciled or NamespaceNotAllowed) and a readable message, plus the Forgejo id of the object it owns. kubectl get shows READY for every kind; kubectl describe shows the reason. All reasons are listed in Reason codes.

Which Forgejo?

Every CR has an optional instanceRef ({name: main}). Leave it out when the cluster has a single ForgejoInstance, which is used by default. With several instances, set it on every CR. A namespace can also bring its own server as a ForgejoLocalInstance. Once a CR is bound to an instance (status.instance), it never moves to another one.

On this page