Welcome to the project, and thanks for considering contributing to this project.
If you have any questions or need clarifications on topics covered here, please feel free to reach out to us on the #cnoe-interest channel on CNCF Slack.
To get started with the project on your machine, you need to install the following tools:
- Go 1.21+. See this official guide from Go authors.
- Make. You can install it through a package manager on your system. E.g. Install
build-essentialfor Ubuntu systems. - Docker. Similar to Make, you can install it through your package manager or Docker Desktop.
Once required tools are installed, clone this repository. git clone https://github.com/cnoe-io/idpbuilder.git.
Then change your current working directory to the repository root. e.g. cd idpbuilder.
All subsequent commands described in this document assumes they are executed from the repository root.
Ensure your docker daemon is running and available. e.g. docker images command should not error out.
- Checkout the main branch.
git checkout main - Build the binary.
make build. This compiles the project. It will take several minutes for the first time. Example output shown below:~/idpbuilder$ make build test -s /home/ubuntu/idpbuilder/bin/controller-gen && /home/ubuntu/idpbuilder/bin/controller-gen --version | grep -q v0.12.0 || \ GOBIN=/home/ubuntu/idpbuilder/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.12.0 /home/ubuntu/idpbuilder/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./api/..." output:crd:artifacts:config=pkg/controllers/resources /home/ubuntu/idpbuilder/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." go fmt ./... go vet ./... go build -o idpbuilder main.go - Once build finishes, you should have an executable file called
idpbuilderin the root of the repository. - The file is ready to use. Execute this command to confirm:
./idpbuilder --help
To test the very basic functionality of idpbuilder, Run the following command: ./idpbuilder create
This command creates a kind cluster, expose associated endpoints to your local machine using an ingress controller and deploy the following packages:
They are deployed as ArgoCD Applications with the Gitea repositories set as their sources.
UIs for Backstage, Gitea, and ArgoCD are accessible on the machine:
- Gitea: https://gitea.cnoe.localtest.me:8443/explore/repos
- Backstage: https://backstage.cnoe.localtest.me:8443/
- ArgoCD: https://argocd.cnoe.localtest.me:8443/applications
Credentials for core packages can be obtained with:
idpbuilder get secretsAs described in the main readme file, the above command is equivalent to running:
kubectl -n argocd get secret argocd-initial-admin-secret
kubectl get secrets -n gitea gitea-admin-secret
kubectl get secrets -A -l cnoe.io/cli-secret=trueAll ArgoCD applications should be synced and healthy. You can check them in the UI or
kubectl get application -n argocd
The process to upgrade a core component: Argo CD, Gitea, Ingress is not so complex but requires to take care about the following points:
- Select the core component to be upgraded and get its current version. See the kustomization file under the
hack/<core-component>folder and the resource YAML file of the resources to be installed - Create a ticket describing the new sibling version of the core component to be bumped
- Bump the version part of the kustomization file. Example for argocd: https://github.com/cnoe-io/idpbuilder/blob/main/hack/argo-cd/kustomization.yaml#L4
- Review the patched files to see if changes are needed (new file(s), files to be deleted or files to be changed). Example for argocd: https://github.com/cnoe-io/idpbuilder/blob/main/hack/argo-cd/kustomization.yaml#L7-L16
- Generate the new resources YAML files using the bash script:
generate-manifests.sh - Build a new idpbuilder binary
- Test it locally like also using the e2e integration test:
make e2e - Review the test cases if changes are needed too
- Update the documentation to detail which version of the core component has been bumped like also for which version (or range of versions) of idpbuilder the new version of the component apply for.
NOTES:
- For some components, it could be possible that you also have to upgrade the version of the go library within the
go.modfile. Example for gitea:code.gitea.io/sdk/gitea v0.16.0 - For Argo CD, we use a separate GitHub project (till a better solution is implemented) packaging a subset of the Argo CD API. Review carefully this file please: https://github.com/cnoe-io/argocd-api?tab=readme-ov-file#read-this-first
This repository requires a Developer Certificate of Origin (DCO) signature.
When preparing to send in a pull request, please make sure your commit is signed. You can achieve this by doing a git commit --sign or git commit -s when making the commit.
The default manifests for the core packages are available here. These are generated by scripts. If you want to make changes to them, see below.
ArgoCD manifests are generated using a bash script available here. This script runs kustomize to modify the basic installation manifests provided by ArgoCD. Modifications include:
- Prevent notification and dex pods from running. This is done to keep the number of pods running low by default.
- Use the annotation tracking instead of the default label tracking. Annotation tracking allows you to avoid problems caused by the label tracking method. In addition, this configuration is required when using Crossplane.
- Support for path based routing.
Gitea manifests are generated using a bash script available here. This script runs helm template to generate most files. See the values file for more information.
ingress-nginx manifests are generated using a bash script available here. This script runs kustomize to modify the basic installation manifests provided by ingress-nginx.
idpbuilder is made of two phases: CLI and Kubernetes controllers.
When the idpbuilder binary is executed, it starts with the CLI phase.
- This is the phase where command flags are parsed and translated into relevant Go structs' fields. Most notably the
LocalBuildstruct. - Create a Kind cluster, then update the kubeconfig file.
- Once the kind cluster is started and relevant fields are populated, Kubernetes controllers are started:
LocalbuildReconcilerresponsible for bootstrapping the cluster with absolute necessary packages. Creates Custom Resources (CRs) and installs embedded manifests.RepositoryReconcilerresponsible for creating and managing Gitea repository and repository contents.CustomPackageReconcilerresponsible for managing custom packages.
- They are all managed by a single Kubernetes controller manager.
- Once controllers are started, CRs corresponding to these controllers are created. For example for Backstage, it creates a GitRepository CR and ArgoCD Application.
- CLI then waits for these CRs to be ready.
During this phase, controllers act on CRs created by the CLI phase. Resources such as Gitea repositories and ArgoCD applications are created.
LocalbuildReconciler bootstraps the cluster using embedded manifests. Embedded manifests are yaml files that are baked into the binary at compile time.
- Install core packages. They are essential services that are needed for the user experiences we want to enable:
- Gitea. This is the in-cluster Git server that hosts Git repositories.
- Ingress-nginx. This is necessary to expose services inside the cluster to the users.
- ArgoCD. This is used as the packaging mechanism. Its primary purpose is to deploy manifests from gitea repositories.
- Once they are installed, it creates
GitRepositoryCRs for core packages. This CR represents the git repository on the Gitea server. - Create ArgoCD applications for the apps. Point them to the Gitea repositories. From here on, ArgoCD manages the core packages.
Once core packages are installed, it creates the other embedded applications: Backstage and Crossplane.
- Create
GitRepositoryCRs for the apps. - Create ArgoCD applications for the apps. Point them to the Gitea repositories.
RepositoryReconciler creates Gitea repositories.
The content of the repositories can either be sourced from Embedded file system or local file system.
CustomPackageReconciler parses the specified ArgoCD application files. If they specify repository URL with the scheme cnoe://,
it creates GitRepository CR with source specified as local, then creates ArgoCD application with the repository URL replaced.
For example, if an ArgoCD application is specified as the following.
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
repoURL: cnoe://busyboxThen, the actual object created is this.
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
repoURL: http://my-gitea-http.gitea.svc.cluster.local:3000/giteaAdmin/idpbuilder-localdev-my-app-busybox.git