Skip to content

Latest commit

 

History

History
329 lines (220 loc) · 14.6 KB

File metadata and controls

329 lines (220 loc) · 14.6 KB

How to Contribute to the OpenTelemetry Operator

We'd love your help!

This project is Apache 2.0 licensed and accepts contributions via GitHub pull requests. This document outlines some of the conventions on development workflow, contact points and other resources to make it easier to get your contribution accepted.

We gratefully welcome improvements to documentation as well as to code.

Getting Started

Pre-requisites

  • Go.
  • Docker version 23.0.0 or greater.

Local development cheat sheet

Essential Commands:

  • make test - Run unit tests
  • make lint - Run golangci-lint
  • make fmt - Format Go code and auto-fix issues
  • make vet - Run go vet
  • make update - Generate code and manifests based on Go struct definitions for CRDs (includes generate, manifests, bundle, api-docs)
  • make precommit - Run all checks: fmt, vet, lint, test, ensure-update-is-noop (run before committing)

Code Generation:

  • make generate - Generate DeepCopy methods for API types
  • make manifests - Generate CRDs, RBAC, webhooks
  • make bundle - Generate OLM bundles (community + openshift)
  • make api-docs - Generate API documentation from CRDs

Building and Deployment:

  • make manager - Build operator binary
  • make container - Build operator container image
  • make deploy - Deploy to connected Kubernetes cluster
  • make cert-manager - Install cert-manager (required for webhooks)

Testing:

  • make e2e - Run general e2e tests
  • make e2e-instrumentation - Auto-instrumentation tests
  • make e2e-targetallocator - Target Allocator tests
  • make e2e-opampbridge - OpAMP Bridge tests
  • make prepare-e2e - Set up kind cluster for e2e testing
  • make stop-kind - Delete kind cluster

Workflow

It is recommended to follow the "GitHub Workflow". When using GitHub's CLI, here's how it typically looks like:

gh repo fork github.com/open-telemetry/opentelemetry-operator
git checkout -b your-feature-branch
# do your changes
git commit -sam "Add feature X"
gh pr create

Make changes to the project manifests

The following command should be run to make sure the project manifests are up-to-date:

make update

The local changes after running the command should be added to the pull request:

The following make target is run on CI to verify the project structure:

make ensure-update-is-noop

Adding new components - webhook, API

The repository structure MUST be compliant with operator-sdk scaffolding, which uses kubebuilder behind the scenes. This is to ensure a valid bundle generation and it makes it easy to maintain the project and add new components.

Refer to the Operator SDK documentation how to generate new APIs, Webhook and other parts of the project.

Local run

Build the manifests, install the CRD and run the operator as a local process:

make install run

Deployment with webhooks

When running make run, the webhooks aren't effective as it starts the manager in the local machine instead of in-cluster. To test the webhooks, you'll need to:

  1. Configure a proxy between the Kubernetes API server and your host, so that it can contact the webhook in your local machine
  2. Create the TLS certificates and place them, by default, on /tmp/k8s-webhook-server/serving-certs/tls.crt. The Kubernetes API server has also to be configured to trust the CA used to generate those certs.

In general, it's just easier to deploy the operator in a Kubernetes cluster instead. For that, you'll need the cert-manager installed. You can install it by running:

make cert-manager

The environment variable CERTMANAGER_VERSION can be used to override the cert-manager version:

CERTMANAGER_VERSION=1.60 make cert-manager

When deploying the operator into the cluster using make deploy, an image in the format ghcr.io/${DOCKER_USER}/opentelemetry-operator is generated. If this format isn't suitable, it can be overridden by:

  • IMG_PREFIX, to override the registry, namespace and image name
  • DOCKER_USER, to override the namespace
  • IMG_REPO, to override the repository (opentelemetry-operator)
  • VERSION, to override only the version part
  • IMG, to override the entire image specification
IMG=docker.io/${DOCKER_USER}/opentelemetry-operator:dev-$(git rev-parse --short HEAD)-$(date +%s) make generate container container-push deploy

Your operator will be available in the opentelemetry-operator-system namespace.

Using a private container registry

Ensure the secret regcred has been created to enable opentelemetry-operator-controller-manager deployment to pull images from your private registry.

kubectl create secret docker-registry regcred --docker-server=<registry> --docker-username=${USER} --docker-password=${PASSWORD}  -n opentelemetry-operator-system

Testing

Unit tests

Some unit tests use envtest which requires Kubernetes binaries (e.g. api-server, etcd and kubectl) to be present on the host filesystem. Makefile takes care of installing all dependent binaries, however running the tests from IDE or via go test might not work out-of-the-box. The envtest uses env variable KUBEBUILDER_ASSETS that points to a directory with these binaries. To make the test work in IDE or go test the environment variable has to be correctly set.

Example how to run test that use envtest:

make envtest
KUBEBUILDER_ASSETS=$(./bin/setup-envtest use -p path 1.35) go test ./pkg...

End to end tests

To run the end-to-end tests, you'll need kind and chainsaw. They will be installed automatically in the project's local bin/ directory.

Once they are installed, the tests can be executed with make prepare-e2e, which will build an image to use with the tests, followed by make e2e. Keep in mind that you need to call make prepare-e2e again after you make changes to operator code or manifests.

The tests are located under tests/e2e and are written to be used with chainsaw. Refer to their documentation to understand how tests are written.

To revert the changes made by the make prepare-e2e run make reset.

To delete the kind cluster created by make prepare-e2e run make stop-kind.

OpenShift End to End tests

To run the end-to-end tests written for OpenShift, you'll need a OpenShift cluster.

To install the OpenTelemetry operator, please follow the instructions in Operator Lifecycle Manager (OLM)

Once the operator is installed, the tests can be executed using make e2e-openshift, which will call to the e2e-openshift target. Note that kind is disabled for the TestSuite as the requirement is to use an OpenShift cluster for these test cases.

The tests are located under tests/e2e-openshift and are written to be used with chainsaw.

Undeploying the operator from the local cluster

make undeploy

Project Structure

Directory Organization

  • apis/ - CRD definitions (v1alpha1 experimental, v1beta1 stable)
  • internal/controllers/ - Kubernetes reconciliation controllers
  • internal/manifests/ - Resource generation logic (Deployments, Services, ConfigMaps)
  • internal/instrumentation/ - Auto-instrumentation injection logic per language
  • internal/webhook/podmutation/ - Pod mutation webhooks for sidecar and auto-instrumentation
  • internal/config/ - Collector configuration parsing and manipulation
  • cmd/otel-allocator/ - Target Allocator source code
  • cmd/operator-opamp-bridge/ - OpAMP Bridge source code
  • autoinstrumentation/ - Dockerfiles for instrumentation images
  • config/ - Kubernetes deployment configurations and overlays
  • tests/ - End-to-end test suites (Chainsaw framework)
  • bundle/ - OLM bundle manifests (community and openshift variants)

For a general overview of the API types, check out the official GoDoc or the locally-hosted GoDoc

Core Custom Resources

  • OpenTelemetryCollector (v1beta1) - Manages collector deployments in multiple modes (Deployment, DaemonSet, StatefulSet, Sidecar)
  • Instrumentation (v1alpha1) - Configures auto-instrumentation for workloads (Java, NodeJS, Python, .NET, Go, Apache HTTPD, Nginx)
  • OpAMPBridge (v1alpha1) - Enables remote configuration management via OpAMP protocol
  • TargetAllocator (v1alpha1) - Standalone CR for Prometheus target allocation, or embedded in OpenTelemetryCollector spec

Code Style and Conventions

Go Code Style

  • Follow standard Go conventions (gofmt, go vet)
  • Use golangci-lint configuration in .golangci.yaml - run make golangci-lint to check
  • Run make fmt before committing - it auto-fixes many issues
  • Never edit zz_generated.*.go files - they're auto-generated
  • Use functions in internal/naming/ for consistent resource naming
  • Follow Kubernetes naming: lowercase, hyphens, DNS-compatible

Kubebuilder Markers

When adding fields to CRD structs in apis/, use kubebuilder markers for validation:

type MySpec struct {
    // +kubebuilder:validation:Required
    // +kubebuilder:validation:MinLength=1
    RequiredField string `json:"requiredField"`

    // +optional
    OptionalField *string `json:"optionalField,omitempty"`
}

Common Tasks

Changing API types (CRDs)

  1. Edit structs in apis/v1alpha1/ or apis/v1beta1/
  2. Add/update kubebuilder markers for validation
  3. Run make update - generates manifests, bundles, docs
  4. Run make precommit - ensures everything is valid
  5. Verify CRD changes: git diff config/crd/bases/

CRITICAL: Always run make update after API changes. CI will fail with "ensure-update-is-noop" if you forget.

Changing controller logic

  1. Modify reconciliation logic in internal/controllers/
  2. Update corresponding manifest generation in internal/manifests/ if needed
  3. Add/update unit tests
  4. Run make test to verify
  5. For complex changes, add e2e test in appropriate tests/e2e-*/ directory

Changing webhooks

  1. Modify webhook logic in internal/webhook/
  2. Webhooks cannot be tested with make run - must use make deploy
  3. Set up kind cluster: make prepare-e2e
  4. Add e2e test to verify webhook behavior

Adding new auto-instrumentation language

  1. Add Dockerfile in autoinstrumentation/{language}/
  2. Add injection logic in internal/instrumentation/{language}.go
  3. Add spec field to apis/v1alpha1/instrumentation_types.go
  4. Update webhook to handle new annotation
  5. Add feature gate flag in main.go
  6. Add e2e test in tests/e2e-instrumentation/
  7. Update versions.txt
  8. Run make update

Contributing

Your contribution is welcome! For it to be accepted, we have a few standards that must be followed.

If you are contributing to sync the receivers from otel-collector-contrib, note that the operator only synchronizes receivers that aren't scrapers, as there's no need to open ports in services for this case. In general, receivers would open a UDP/TCP port and the operator should be adding an entry in the Kubernetes Service resource accordingly.

New features

Before starting the development of a new feature, please create an issue and discuss it with the project maintainers. Features should come with documentation and enough tests (unit and/or end-to-end).

Bug fixes

Every bug fix should be accompanied by a unit test, so that we can prevent regressions.

Documentation, typos, ...

They are mostly welcome!

Adding a Changelog Entry

The CHANGELOG.md file in this repo is autogenerated from .yaml files in the ./.chloggen directory.

Your pull-request should add a new .yaml file to this directory. The name of your file must be unique since the last release.

During the collector release process, all ./.chloggen/*.yaml files are transcribed into CHANGELOG.md and then deleted.

If a changelog entry is not required, add either [chore] to the title of the pull request or add the "Skip Changelog" label to disable this action.

Recommended Steps

  1. Create an entry file using make chlog-new. This generates a file based on your current branch (e.g. ./.chloggen/my-branch.yaml)
  2. Fill in all fields in the new file
  3. Run make chlog-validate to ensure the new file is valid
  4. Commit and push the file

Alternately, copy ./.chloggen/TEMPLATE.yaml, or just create your file from scratch.

Operator Lifecycle Manager (OLM)

For production environments, it is recommended to use the Operator Lifecycle Manager (OLM) to provision and update the OpenTelemetry Operator. Our operator is available in the Operator Hub, and when making changes involving those manifests the following steps can be used for testing. Refer to the OLM documentation for more complete information.

Setup OLM

When using Kubernetes, install OLM following the official instructions. At the moment of this writing, it involves the following:

operator-sdk olm install

When using OpenShift, the OLM is already installed.

Create the bundle and related images

The following commands will generate two bundles (one for regular Kubernetes and another one for OpenShift) under bundle/, build an image with its contents, build and publish the operator image.

BUNDLE_IMG=docker.io/${USER}/opentelemetry-operator-bundle:latest IMG=docker.io/${USER}/opentelemetry-operator:latest make bundle container container-push bundle-build bundle-push

Install the operator

operator-sdk run bundle docker.io/${DOCKER_USER}/opentelemetry-operator-bundle:latest

Uninstall the operator

The operator can be uninstalled by deleting subscriptions.operators.coreos.com and clusterserviceversion.operators.coreos.com objects from the current namespace.

kubectl delete clusterserviceversion.operators.coreos.com --all
kubectl delete subscriptions.operators.coreos.com --all