# Project Config

## Overview

The Project Config represents the configuration of a KubeBuilder project. All projects that you scaffold with the CLI (KB version 3.0 and higher) generate the `PROJECT` file in the projects' root directory. Therefore, it stores all plugins and input data you used to generate the project and APIs to better enable plugins to make useful decisions when scaffolding.

## Example

Following is an example of a PROJECT config file which is the result of a project generated with two APIs using the [Deploy Image Plugin][deploy-image-plugin].

```yaml
# Code generated by tool. DO NOT EDIT.
# This file is used to track the info used to scaffold your project
# and allow the plugins properly work.
# More info: ./project-config.md
domain: testproject.org
cliVersion: v4.6.0
layout:
  - go.kubebuilder.io/v4
plugins:
  deploy-image.go.kubebuilder.io/v1-alpha:
    resources:
      - domain: testproject.org
        group: example.com
        kind: Memcached
        options:
          containerCommand: memcached,--memory-limit=64,-o,modern,-v
          containerPort: "11211"
          image: memcached:1.4.36-alpine
          runAsUser: "1001"
        version: v1alpha1
      - domain: testproject.org
        group: example.com
        kind: Busybox
        options:
          image: busybox:1.28
        version: v1alpha1
projectName: project-v4-with-deploy-image
repo: sigs.k8s.io/kubebuilder/testdata/project-v4-with-deploy-image
resources:
  - api:
      crdVersion: v1
      namespaced: true
    controller: true
    domain: testproject.org
    group: example.com
    kind: Memcached
    path: sigs.k8s.io/kubebuilder/testdata/project-v4-with-deploy-image/api/v1alpha1
    version: v1alpha1
    webhooks:
      validation: true
      webhookVersion: v1
  - api:
      crdVersion: v1
      namespaced: true
    controller: true
    domain: testproject.org
    group: example.com
    kind: Busybox
    path: sigs.k8s.io/kubebuilder/testdata/project-v4-with-deploy-image/api/v1alpha1
    version: v1alpha1
  - controller: true
    domain: io
    external: true
    group: cert-manager
    kind: Certificate
    path: github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1
    module: github.com/cert-manager/cert-manager@v1.18.2
    version: v1
version: "3"
```
## Why store the plugins and data used?

Following some examples of motivations to track the input used:
- check if a plugin can or cannot be scaffolded on top of an existing plugin (i.e.) plugin compatibility while chaining multiple of them together.
- what operations can or cannot be done such as verify if the layout allow API(s) for different groups to be scaffolded for the current configuration or not.
- verify what data can or not be used in the CLI operations such as to ensure that WebHooks can only be created for pre-existent API(s)

Note that KubeBuilder is not only a CLI tool but can also be used as a library to allow users to create their plugins/tools, provide helpers and customizations on top of their existing projects - an example of which is [Operator-SDK][operator-sdk]. SDK leverages KubeBuilder to create plugins to allow users to work with other languages and provide helpers for their users to integrate their projects with, for example, the [Operator Framework solutions/OLM][olm]. You can check the [plugin's documentation][plugins-doc] to know more about creating custom plugins.

Additionally, another motivation for the PROJECT file is to help us to create a feature that allows users to easily upgrade their projects by providing helpers that automatically re-scaffold the project. By having all the required metadata regarding the APIs, their configurations and versions in the PROJECT file. For example, it can be used to automate the process of re-scaffolding while migrating between plugin versions. ([More info][doc-design-helper]).

## Versioning

The Project config is versioned according to its layout. For further information see [Versioning][versioning].

## Layout definition

The `PROJECT` version `3` layout looks like:

```yaml
domain: testproject.org
cliVersion: v4.6.0
layout:
  - go.kubebuilder.io/v4
plugins:
  deploy-image.go.kubebuilder.io/v1-alpha:
    resources:
      - domain: testproject.org
        group: example.com
        kind: Memcached
        options:
          containerCommand: memcached,--memory-limit=64,-o,modern,-v
          containerPort: "11211"
          image: memcached:memcached:1.6.26-alpine3.19
          runAsUser: "1001"
        version: v1alpha1
      - domain: testproject.org
        group: example.com
        kind: Busybox
        options:
          image: busybox:1.36.1
        version: v1alpha1
projectName: project-v4-with-deploy-image
repo: sigs.k8s.io/kubebuilder/testdata/project-v4-with-deploy-image
resources:
  - api:
      crdVersion: v1
      namespaced: true
    controller: true
    domain: testproject.org
    group: example.com
    kind: Memcached
    path: sigs.k8s.io/kubebuilder/testdata/project-v4-with-deploy-image/api/v1alpha1
    version: v1alpha1
    webhooks:
      validation: true
      webhookVersion: v1
  - api:
      crdVersion: v1
      namespaced: true
    controller: true
    domain: testproject.org
    group: example.com
    kind: Busybox
    path: sigs.k8s.io/kubebuilder/testdata/project-v4-with-deploy-image/api/v1alpha1
    version: v1alpha1
  - controller: true
    domain: io
    external: true
    group: cert-manager
    kind: Certificate
    path: github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1
    module: github.com/cert-manager/cert-manager@v1.18.2
    version: v1
version: "3"
```

Now let us check its layout fields definition:

| Field                               | Description                                                                                                                                                                                                                                                                     |
|-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `cliVersion`                | Used to record the specific CLI version used during project scaffolding with `init`. Helps identifying the version of the tooling employed, aiding in troubleshooting and ensuring compatibility with updates.                                           |
| `layout`                            | Defines the global plugins, e.g. a project `init` with `--plugins="go/v4,deploy-image/v1-alpha"` means that any sub-command used will always call its implementation for both plugins in a chain.                                                                               |
| `domain`                            | Store the domain of the project. This information can be provided by the user when the project is generate with the `init` sub-command and the `domain` flag.                                                                                                                   |
| `plugins`                           | Defines the plugins used to do custom scaffolding, e.g. to use the optional `deploy-image/v1-alpha` plugin to do scaffolding for just a specific api via the command `kubebuider create api [options] --plugins=deploy-image/v1-alpha`.                                         |
| `projectName`                       | The name of the project. This is used to scaffold the manager data. By default it is the name of the project directory, however, it can be provided by the user in the `init` sub-command via the `--project-name` flag.                                                   |
| `repo`                              | The project repository which is the Golang module, e.g `github.com/example/myproject-operator`.                                                                                                                                                                                 |
| `multigroup`                        | **(Optional)** When set to `true`, enables multi-group project layout. APIs are organized into group-specific directories (`api/<group>/<version>/`). Can be set during initialization via `kubebuilder init --multigroup` or enabled/disabled later via `kubebuilder edit --multigroup`. Default is `false` (omitted from PROJECT file). |
| `namespaced`                        | **(Optional)** When set to `true`, configures the project for namespace-scoped deployment. The operator will only watch and manage resources within its deployment namespace, using namespace-scoped RBAC (`Role`/`RoleBinding` instead of `ClusterRole`/`ClusterRoleBinding`). Can be enabled/disabled via `kubebuilder edit --namespaced`. Default is `false` (cluster-scoped, omitted from PROJECT file). |
| `resources`                         | An array of all resources that you scaffolded in the project.                                                                                                                                                                                                                 |
| `resources.api`                     | The API scaffolded in the project via the sub-command `create api`.                                                                                                                                                                                                             |
| `resources.api.crdVersion`          | The Kubernetes API version (`apiVersion`) used to do the scaffolding for the CRD resource.                                                                                                                                                                                      |
| `resources.api.namespaced`          | The API RBAC permissions which can be namespaced or cluster scoped.                                                                                                                                                                                                             |
| `resources.api.ssa`                 | **(Optional, Alpha)** When set to `true`, the API was scaffolded with Server-Side Apply support via `create api --ssa`. The scaffold adds the `+genclient` marker and generates apply configurations for the type. Alpha feature: it may change in future releases. Default is `false` (omitted from the PROJECT file). |
| `resources.controller`              | Indicates whether you scaffolded a controller for the API.                                                                                                                                                                                                                      |
| `resources.domain`                  | The domain of the resource that you provided by the `--domain` flag when you initialized the project or via the flag `--external-api-domain` when you used it to scaffold controllers for an [External Type][external-type].                                                   |
| `resources.group`                   | The GKV group of the resource that you provide by the `--group` flag when you use the sub-command `create api`.                                                                                                                                                                |
| `resources.version`                 | The GKV version of the resource that you provide by the `--version` flag when you use the sub-command `create api`.                                                                                                                                                            |
| `resources.kind`                    | Stores the GKV Kind of the resource that you provide by the `--kind` flag when you use the sub-command `create api`.                                                                                                                                                                |
| `resources.path`                    | The import path for the API resource. It is `<repo>/api/<kind>` unless the API added to the project is an external or core-type. For the core-types scenarios, the paths used are mapped [here][core-types]. Or either the path informed by the flag `--external-api-path` |
| `resources.core`                    | It is `true` when  the group used is from Kubernetes API and the API resource is not defined on the project.                                                                                                                                                                    |
| `resources.external`                | It is `true` when you use the flag `--external-api-path` to generate the scaffold for an [External Type][external-type].                                                                                                                                                     |
| `resources.module`                  | **(Optional)** The Go module path for external API dependencies, optionally including a version (e.g., `github.com/cert-manager/cert-manager@v1.18.2` or just `github.com/cert-manager/cert-manager`). Only used when `external` is `true`. Provided via the `--external-api-module` flag to explicitly pin a specific version in `go.mod` or to specify the module when it cannot be automatically determined from `--external-api-path`. If not provided, `go mod tidy` will resolve the dependency automatically. |
| `resources.webhooks`                | Stores the webhooks data when you use the sub-command `create webhook`.                                                                                                                                                                                                          |
| `resources.webhooks.spoke`          | Store the API version that acts as the Spoke with the designated Hub version for conversion webhooks.                                                                                                                                                                       |
| `resources.webhooks.webhookVersion` | The Kubernetes API version (`apiVersion`) used to scaffold the webhook resource.                                                                                                                                                                                                |
| `resources.webhooks.conversion`     | It is `true` when the webhook was scaffold with the `--conversion` flag which means that is a conversion webhook.                                                                                                                                                               |
| `resources.webhooks.defaulting`     | It is `true` when the webhook was scaffold with the `--defaulting` flag which means that is a defaulting webhook.                                                                                                                                                               |
| `resources.webhooks.validation`     | It is `true` when the webhook was scaffold with the `--programmatic-validation` flag which means that is a validation webhook.                                                                                                                                                  |

[project]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/testdata/project-v3/PROJECT
[versioning]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/VERSIONING.md#Versioning
[core-types]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/pkg/plugins/golang/options.go
[deploy-image-plugin]: ../plugins/available/deploy-image-plugin-v1-alpha.md
[olm]: https://olm.operatorframework.io/
[plugins-doc]: ../plugins/creating-plugins.html#why-use-the-kubebuilder-style
[doc-design-helper]: https://github.com/kubernetes-sigs/kubebuilder/blob/master/designs/helper_to_upgrade_projects_by_rescaffolding.md
[operator-sdk]: https://sdk.operatorframework.io/
[external-type]: ./using_an_external_resource.md