Skip to content

feat: add GitHub OAuth, KSOPS fixes, and CD workflow#2

Merged
xnoto merged 0 commit intomainfrom
initial-commit
Dec 21, 2025
Merged

feat: add GitHub OAuth, KSOPS fixes, and CD workflow#2
xnoto merged 0 commit intomainfrom
initial-commit

Conversation

@xnoto
Copy link
Copy Markdown
Contributor

@xnoto xnoto commented Dec 21, 2025

Summary

  • Add GitHub OAuth authentication for ArgoCD via Dex with org/team RBAC
  • Fix KSOPS init container (use alpine to download binaries from distroless image)
  • Add CD workflow that syncs ArgoCD on successful CI runs to main
  • Move ClusterRoleBinding back to Ansible, harden Job manifest

@xnoto xnoto merged commit 29e97b7 into main Dec 21, 2025
@xnoto xnoto deleted the initial-commit branch December 21, 2025 19:36
xnoto added a commit that referenced this pull request Apr 29, 2026
…A) (#5)

## Summary

Phase A of the k3s migration: re-targets `kustomize-cluster` from
OpenShift Local (CRC) onto vanilla k3s, consumed by `argocd-operator`
(community, upstream of OpenShift GitOps — same `argoproj.io/v1beta1
ArgoCD` CRD, so the existing `repo:` block with KSOPS/Dex/RBAC works
unchanged).

This is the *minimum* set of changes for ArgoCD to bootstrap
successfully on k3s. Phase B (replace OLM Subscriptions for
cert-manager/awx/grafana with upstream Helm) and Phase C (clean up
`openshift-monitoring` Prometheus scrape refs, `system:openshift:scc`
references in workloads) follow as separate PRs.

Bundles the previously-staged repo-local opencode config (the prior
commit on this branch).

### Renames

- namespace `openshift-gitops` → `argocd` (~22 files)
- ArgoCD CR `name: openshift-gitops` → `name: argocd`
- SA `openshift-gitops-argocd-application-controller` →
`argocd-argocd-application-controller`
- directory `workloads/openshift-gitops/` → `workloads/argocd/`
- service ref `argocd-server.openshift-gitops.svc.cluster.local` →
`argocd-server.argocd.svc.cluster.local`
- TunnelBinding subject `openshift-gitops-server` → `argocd-server`
- PostSync hooks: `oc` → `kubectl`, OpenShift CLI ImageStream →
`bitnami/kubectl:latest`
- ci-token-sync image:
`image-registry.openshift-image-registry.svc:5000/public-registry/gh-cli`
→ `ghcr.io/makeitworkcloud/gh-cli`

### Deletions (OpenShift-only constructs)

- `bootstrap/console-branding/` — OpenShift web console branding
- `bootstrap/secrets/openshift-oauth/` — cluster-wide OpenShift OAuth
provider config; ArgoCD's own Dex GitHub SSO remains the SSO path
- `bootstrap/public-registry.yaml` — OpenShift internal-registry-backed
namespace
- `operators/cert-manager/{ingress-patch,openshift-ingress-config}.yaml`
— patched OpenShift's IngressController + componentRoutes
- `operators/cert-manager/wildcard-certificate.yaml` — the wildcard
`*.apps.makeitwork.cloud` LE cert was a CRC ingress workaround. With
public traffic flowing through Cloudflare Tunnels (already in this repo
via `cloudflare-operator` + `TunnelBinding`), TLS terminates at
Cloudflare's edge and an in-cluster wildcard cert is dead code.
- `workloads/arc/imagestream.yaml` — OpenShift ImageStream

### Bootstrap chain

```
tfroot-libvirt k3s cloud-init runcmd:
  1. Install k3s
  2. Create ns argocd + sops-age-keys Secret (in argocd ns)
  3. kubectl apply -k argocd-operator (community)
  4. kubectl apply -k kustomize-cluster//bootstrap?ref=main
       → applies argocd-config.yaml (operator reconciles → argocd-server with KSOPS init)
       → applies bootstrap-secrets-app, gitops-operators, gitops-workloads (sit dormant until argocd-server is up)
  5. argocd-server starts → picks up Applications → self-manages from here
```

The argocd-operator install + sops-age-keys Secret + bootstrap apply is
in the **companion tfroot-libvirt PR #2**. The `sops_age_key` value
needs to be added to `tfroot-libvirt/secrets/secrets.yaml`
(sops-encrypted; same age recipient as the rest).

## Test plan

- [x] `kustomize build bootstrap/` passes locally
- [x] `kustomize build workloads/apps/` passes locally
- [x] All pre-commit hooks (yaml lint, KubeLinter, EOF/whitespace) pass
- [x] CI `Pre-commit Tests` job passes (now `ubuntu-latest`)
- [x] Apply locally (after tfroot-libvirt is also applied) — verify
ArgoCD comes up, repo-server has KSOPS init-container, root sync starts
- [x] Expected red items in ArgoCD UI after sync: cert-manager / awx /
grafana OLM Subscriptions (Phase B will replace), grafana scrape refs to
`openshift-monitoring` (Phase C)

## Migration notes for operators

- The OLM-installed operators (cert-manager, awx, grafana) **will fail
to sync** on k3s because there's no OLM. Their `operator.yaml`
Subscription resources land in etcd but go nowhere. Expected; see Phase
B.
- The wildcard cert is gone. Anything that previously consumed
`wildcard-apps-makeitwork-cloud-tls` Secret (none currently in repo)
will need re-plumbing through Cloudflare.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
xnoto added a commit that referenced this pull request Apr 30, 2026
## Summary

Two unrelated bugs surface together as a blocked `gitops-operators`
Application after the OpenShift→k3s migration in #6b3abd0:

- **OLM-only manifests in `operators/`.** `cert-manager/operator.yaml`,
`cert-manager/apiserver-config.yaml`,
`cert-manager/certmanager-config.yaml`, plus the `ansible/` and
`grafana/` operator manifests are all OLM Subscriptions / OperatorHub
CRs. Their CRDs don't exist on k3s, so kustomize build → server-side
apply fails with `no matches for kind "Subscription"` etc.
- **Stale ksops generator.** `operators/generator/ksops-generator.yaml`
had its only `files:` entry pointing at `arc/dindsystem.yaml`, which was
removed in `945130b` (selective-field-encryption refactor). Kustomize
build aborts with `no such file or directory`.

This PR:

- Deletes `operators/generator/ksops-generator.yaml`. Per-subdir ksops
generators in `arc/`, `cert-manager/`, `cloudflare/`,
`bootstrap/secrets/`, `workloads/*/` cover all secret decryption —
there's no centralized pipeline being lost.
- Strips `operators/cert-manager/` down to `cluster-issuer.yaml` +
`cloudflare-api-token-secret.yaml` (kept) +
`ksops-cert-manager-secrets.yaml` (kept). Cert-manager itself is
bootstrap-installed by `tfroot-libvirt` cloud-init now (see paired PR
there); the `--dns01-recursive-nameservers` controller args from the
deleted `CertManager` CR are applied directly to the upstream Deployment
by cloud-init.
- Comments out `ansible` and `grafana` from
`operators/kustomization.yaml`. Re-enable once they're rewritten as
upstream operator manifests (Phase B).
- **Also:** `bootstrap/ci-token-sync-job.yaml` gets `runAsUser: 1000` so
the Job's `runAsNonRoot=true` actually validates against `gh-cli`'s `gh`
user (paired with the images-repo PR pinning `USER 1000` numerically).

## Pairs with

- `tfroot-libvirt` PR #2 — bootstraps cert-manager from cloud-init.
- `images` PR — `gh-cli` switches to numeric `USER 1000`.

## Test plan

- [x] `kustomize build operators/` succeeds (no missing-file or
unknown-kind errors)
- [x] On the live cluster, `bootstrap-secrets` Application is Synced +
Healthy
- [x] After merge: `gitops-operators` Application reaches Synced +
Healthy (pending push so ArgoCD picks it up)
- [x] After merge: `ci-token-sync` Job runs to completion, syncs the
deploy token to GitHub

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant