# Example: rancher-kc-crd plugin (membership-sync only, CRD-driven)
#
# This plugin writes ManagedRancherProject CRDs to a Kubernetes cluster
# running rancher-keycloak-operator; the operator does the actual
# Rancher project + Keycloak group work. Recommended operator: 0.3.1+.
#
# Each Waldur Resource is 1:1 with a Rancher downstream cluster -- the
# plugin reads the cluster ID from `resource.backend_id` at CR-build
# time. One offering can therefore hold N Resources targeting N
# different clusters. There is no offering-level cluster_id setting:
# if a resource's backend_id is empty, CR build raises a clear error
# rather than silently emitting an invalid CR.

offerings:
  - name: "rancher-kc-crd-aio"

    # Waldur API
    waldur_api_url: "https://waldur.example.com/api/"
    waldur_api_token: "your-waldur-api-token"
    waldur_offering_uuid: "offering-uuid-of-the-rancher-service"

    # Backend wiring — note this plugin is ONLY a membership_sync_backend.
    # Order processing and reporting still need other backends (or none).
    backend_type: "rancher-kc-crd"
    membership_sync_backend: "rancher-kc-crd"

    backend_settings:
      # ── Required ──────────────────────────────────────────────────

      # Waldur SDK access (used by pull_resource to fetch
      # ResourceProjects + UserRoles for the resources sold by this
      # offering). Without these, pull_resource is a no-op and the
      # backend can only be exercised from external callers
      # (apply_resource_project) — useful for tests, not production.
      waldur_api_url: "https://waldur.example.com/api/"
      waldur_api_token: "${WALDUR_API_TOKEN}"
      waldur_verify_ssl: true

      # Namespace where ManagedRancherProject CRs are created. The
      # operator must be watching this same namespace.
      namespace: "waldur-system"

      # Map Waldur offering role names → Rancher role template IDs.
      # Roles not listed here are skipped (operator can't bind them).
      role_map:
        project_member: "project-member"
        project_admin: "project-owner"
        create_ns: "create-ns"

      # ── Optional: Kubernetes connection ──────────────────────────

      # Either point at a kubeconfig file...
      kubeconfig_path: "~/.kube/config"
      context: "aio-rancher"
      # ...or omit kubeconfig_path and rely on in-cluster service-account
      # credentials when the agent is itself running in the operator's
      # cluster.

      # ── Optional: Keycloak group naming ──────────────────────────

      # The operator creates a TWO-LEVEL Keycloak group hierarchy per CR:
      #
      #   parent_group_name (one per cluster, organisational container)
      #     └── group_name_template-rendered child group (the one actually
      #         bound to the Rancher project's PRTB and where users are
      #         added)
      #
      # Concrete example with the defaults below, for cluster "c-m-abc12345"
      # and ResourceProject UUID "8706dd1a..." with role "project_member":
      #
      #   c_c-m-abc12345              <- parent group (cluster container)
      #     └── c_c-m-abc12345_8706dd1a_project_member  <- child group
      #
      # The child group's Keycloak ID is what gets passed to Rancher in
      # the projectroletemplatebinding (PRTB), which is how OIDC users
      # actually gain access to the Rancher project. Adding a user to the
      # child group = granting them that role on that project, and only
      # that project (because the group is per-project, not shared).
      #
      # Template variables understood by BOTH fields:
      #
      #   Stable identifiers (immutable):
      #     ${cluster_id}      Rancher cluster ID (resource.backend_id)
      #     ${role_name}       Waldur role name (pre-mapping)
      #     ${rp_uuid}         ResourceProject UUID, full 32-char hex
      #     ${rp_uuid_short}   First 8 hex chars of ${rp_uuid} -- ~4B
      #                        combos, collision-free in practice within
      #                        a (cluster, role) tuple. Use this for
      #                        readable templates that still need a per-RP
      #                        discriminator.
      #
      #   Human-readable (mutable -- renaming the entity in Waldur creates
      #   a new Keycloak group and orphans the old one):
      #     ${customer_slug}   Waldur Customer (organization) slug
      #     ${project_slug}    Waldur Project slug (the parent project that
      #                        owns the Resource, NOT the ResourceProject)
      #     ${resource_slug}   Waldur Resource slug (1:1 with cluster)
      #     ${project_name}    Human-readable project name (may have spaces)
      #
      # Default child template `c_${cluster_id}_${rp_uuid}_${role_name}`
      # gives each (cluster x project x role) its OWN group -- required
      # for correct per-project access in Rancher. Any custom template
      # MUST include a per-project discriminator (${rp_uuid},
      # ${rp_uuid_short}, or ${project_name}); without it, multiple
      # projects share one group and a user added to project A also
      # gains access to B, C, ... via the shared group's PRTBs.
      #
      # Recommended human-readable opt-in template:
      #   c_${cluster_id}_${customer_slug}_${project_slug}_${rp_uuid_short}_${role_name}
      # Renders e.g. "c_c-m-glwxdksp_hpc-demo-org_genomics-2026_8706dd1a_project_member"
      #
      # WARNING: changing the template after deployment leaves
      # previously-named Keycloak groups orphaned (the operator adopts
      # groups by name and never renames adopted groups). Memberships in
      # the old groups become stale; plan a one-time manual migration if
      # you switch templates against an existing deployment.
      parent_group_name: "c_${cluster_id}"
      group_name_template: "c_${cluster_id}_${rp_uuid}_${role_name}"

      # ── Optional: Keycloak user lookup ───────────────────────────

      # Identifier the operator uses to look up users in Keycloak.
      # false (default) = pass Waldur username, matched against
      #                   keycloak.user.username. Works in both OIDC
      #                   and self-hosted Waldur as long as Waldur
      #                   usernames align with Keycloak ones (the
      #                   typical OIDC mapping does this via the
      #                   `preferred_username` claim).
      # true            = pass Waldur UUID, matched against
      #                   keycloak.user.id. Only correct when Waldur
      #                   was OIDC-provisioned and its user UUIDs
      #                   were seeded from the Keycloak `sub` claim.
      # The default is False because it works in both topologies and
      # tolerates UUID divergence; True is opt-in only.
      keycloak_use_user_id: false

      # ── Optional: cluster-scope role mapping (operator 0.4.0+) ───
      #
      # Maps Waldur Resource-level role names → Rancher CLUSTER role
      # template IDs. When set, every CR for this offering carries a
      # `spec.cluster.keycloak.roleBindings` block built from the
      # Resource's user-roles (one set, fanned out across the per-RP
      # CRs the agent emits). The operator de-duplicates the underlying
      # CRTBs by (clusterId, principal, role).
      #
      # Cluster groups are intentionally shared across all RPs within
      # a Resource -- the `cluster_group_name_template` default below
      # has NO ${rp_uuid} discriminator, since the binding IS cluster-
      # wide. The literal "cluster" segment guards against collisions
      # with the project-scope template (which always carries an
      # ${rp_uuid} hex prefix).
      #
      # Without this section the cluster bindings are not emitted, and
      # the operator behaves as in 0.3.x. Requires operator 0.4.0+ --
      # earlier operators reject `spec.cluster` via CRD validation.
      cluster_role_map:
        resource_member: "cluster-member"
        resource_admin: "cluster-owner"

      # Override the default cluster-scope group name. Available variables
      # (same set as group_name_template, plus the Resource-side slugs;
      # ${rp_uuid} / ${rp_uuid_short} / ${project_name} are NOT useful
      # at cluster scope -- the binding spans all RPs of the Resource):
      #   ${cluster_id}      Rancher cluster ID
      #   ${role_name}       Waldur Resource-level role name (pre-mapping)
      #   ${customer_slug}   Waldur Customer (organization) slug
      #   ${resource_slug}   Waldur Resource slug (1:1 with cluster)
      #   ${project_slug}    Waldur Project slug (parent of the Resource)
      #
      # Default below is the safe minimum; the literal "cluster" segment
      # guards against name collisions with the project-scope template
      # (which always carries an rp_uuid hex prefix).
      #
      # Recommended human-readable opt-in:
      #   c_${cluster_id}_${customer_slug}_${resource_slug}_cluster_${role_name}
      # Renders e.g. "c_c-m-glwxdksp_hpc-demo-org_adamas-cluster_cluster_resource_member"
      cluster_group_name_template: "c_${cluster_id}_cluster_${role_name}"
