Contributing to k8gb

k8gb is licensed under Apache 2 License and accepts contributions via GitHub pull requests. This document outlines the resources and guidelines necessary to follow by contributors to the k8gb project.

Getting started

Getting help

Feel free to ask for help and join the discussions at k8gb community discussions forum. We have dedicated #k8gb channel on Cloud Native Computing Foundation (CNCF) Slack, and we can also actively monitoring #sig-multicluster channel on Kubernetes Slack.

Reporting issues

Reporting bugs is one of the best ways to contribute. Feel free to open an issue describing your problem or question.

Contribution flow

Following is a rough outline for the contributor's workflow:

Local setup

Deploy k8gb locally

make deploy-full-local-setup

deploys k8gb from scratch, including:

Upgrade k8gb to local candidate

make upgrade-candidate

performs upgrade of k8gb helm chart and controller to the testing version built from your current development tree.

Overriding dev environment settings

Sometimes there is a need to override environment variables used by make targets for local k8gb development. This can be easily achieved by providing the list of environment variables with respective values in the .env file at the local repository root:

cat .env

# .env:
LOG_LEVEL=info
LOG_FORMAT=json

Overrides done this way can persist between terminal sessions and can be used as a single point of configuration for development in terminal and IDE of choice.

Testing

Unit testing

Use make test to check your implementation changes.

Testing against real k8s clusters

There is a possibility to execute the integration terratest suite over the real clusters. For this, you need to override the set of test settings as in the example below.

PRIMARY_GEO_TAG=af-south-1 \
SECONDARY_GEO_TAG=eu-west-1 \
DNS_SERVER1=a377095726f1845fb85b95c2afef8ac0-9a1a10f24e634e28.elb.af-south-1.amazonaws.com \
DNS_SERVER1_PORT=53 \
DNS_SERVER2=a873f5c83be624a0a84c05a743d598a8-443f7e0285e4a28f.elb.eu-west-1.amazonaws.com \
DNS_SERVER2_PORT=53 \
GSLB_DOMAIN=test.k8gb.io \
K8GB_CLUSTER1=arn:aws:eks:af-south-1:<aws-account-id>:cluster/k8gb-cluster-af-south-1 \
K8GB_CLUSTER2=arn:aws:eks:eu-west-1:<aws-account-id>:cluster/k8gb-cluster-eu-west-1 \
make terratest

Debugging

  1. Install Delve debugger first. Follow the installation instructions for specific platforms from Delve's website.

  2. Run delve with options specific to IDE of choice. There is a dedicated make target available for Goland:

    make debug-idea
    

    This article describes possible option examples for Goland and VS Code.

  3. Attach debugger of your IDE to port 2345.

Metrics

More info about k8gb metrics can be found in the metrics.md document. If you need to check and query the k8gb metrics locally, you can install a Prometheus in the local clusters using the make deploy-prometheus command.

The deployed Prometheus scrapes metrics from the dedicated k8gb operator endpoint and makes them accessible via Prometheus web UI:

All the metric data is ephemeral and will be lost with pod restarts. To uninstall Prometheus, run make uninstall-prometheus

Optionally, you can also install Grafana that will have the datasources configured and example dashboard ready using make deploy-grafana

Code style

k8gb project is using the coding style suggested by the Golang community. See the golang-style-doc for details.

Please follow this style to make k8gb easy to review, maintain and develop. Run make check to automatically check if your code is compliant.

Logging

k8gb project is using the zerolog library for logging.

Error handling

See effective go errors first. Do not discard errors using _ variables except tests, or, in truly exceptional situations. If a function returns an error, check it to make sure the function succeeded. If the function fails, consider logging the error and recording errors in metrics (see: logging recommendations).

The following example demonstrates error handling inside the reconciliation loop:

	var log = logging.Logger()

	var m = metrics.Metrics()
	...
	err = r.DNSProvider.CreateZoneDelegationForExternalDNS(gslb)
	if err != nil {
		log.Err(err).Msg("Unable to create zone delegation")
		m.ErrorIncrement(gslb)
		return result.Requeue()
	}

Commit and Pull Request message

We follow a rough convention for PR and commit messages, which is designed to answer two questions: what changed and why. The subject line should feature the what, and the body of the message should describe the why. The format can be described more formally as follows:

<what was changed>

<why this change was made>

<footer>

The first line is the subject and should be no longer than 70 characters. The second line is always blank. Consequent lines should be wrapped at 80 characters. This way, the message is easier to read on GitHub as well as in various git tools.

scripts: add the test-cluster command

This command uses "k3d" to set up a test cluster for debugging.

Fixes #38

Commit message can be made lightweight unless it is the only commit forming the PR. In that case, the message can follow the simplified convention:

<what was changed and why>

This convention is useful when several minimalistic commit messages are going to form PR descriptions as bullet points of what was done during the final squash and merge for PR.

Signature

As a CNCF project, k8gb must comply with Developer Certificate of Origin (DCO) requirement. DCO GitHub Check automatically enforces DCO for all commits. Contributors are required to ensure that every commit message contains the following signature:

Signed-off-by: NAME SURNAME <email@address.example.org>

The best way to achieve this automatically for local development is to create the following alias in the ~/.gitconfig file:

[alias]
ci = commit -s

When a commit is created in GitHub UI as a result of accepted suggested change, the signature should be manually added to the "optional extended description" field.

Changelog

The CHANGELOG is automatically generated from Github PRs and Issues during release. Use dedicated keywords in PR message or manual PR and Issue linking for clean changelog generation. Issues and PRs should be also properly tagged with valid project tags ("bug", "enhancement", "wontfix", etc )

Documentation

If contribution changes the existing APIs or user interface, it must include sufficient documentation explaining the use of the new or updated feature.

k8gb.io website

k8gb.io website is a Jekyll-based static website generated from project markdown documentation and hosted by GitHub Pages. gh-pages branch contains the website source, including configuration, website layout, and styling. Markdown documents are automatically populated to gh-pages from the main branch and should be authored there. Changes to the k8gb.io website layout and styling should be checked out from the gh-pages branch and PRs should be created against gh-pages.

Local website authoring and testing

These instructions will help you to set up and use local website authoring and testing environment:

Using custom SSL CA certificate

When the dev environment is behind a proxy, it might be required to use a custom SSL CA certificate, otherwise, Jekyll is not able to update its plugins and dependencies. Local website authoring target automatically detects and wires the SSL certificate to its docker container from the path provided by the CUSTOM_CERT_PATH environment variable:

export CUSTOM_CERT_PATH=/path/to/custom/certificate.pem

NOTE: Certificate should be in a PEM format

.env support

Environment variables can be stored in a local .env file in the project's root to retain their persistency between the authoring sessions:

JEKYLL_GITHUB_TOKEN=<your-github-token>
CUSTOM_CERT_PATH=<your-custom-ssl-certificate>

End-to-end demo helper

The demo helper is designed to work with podinfo that was deployed by

make deploy-test-apps

It will configure podinfo to expose geotag as part of an HTTP response.

To test and/or demonstrate continuous query to GSLB enabled endpoint execute

make demo DEMO_URL=https://failover.test.exampledns.tk

The happy path will look like:

[Thu May 27 15:35:26 UTC 2021] ...

200  "message": "eu-west-1",

[Thu May 27 15:35:31 UTC 2021] ...

200
  "message": "eu-west-1",
[Thu May 27 15:35:36 UTC 2021] ...

The sources for demo helper images can be found here

To enable verbose debug output declare DEMO_DEBUG=1 like

make demo DEMO_URL=https://failover.test.exampledns.tk DEMO_DEBUG=1

Release process

Congratulations, the release is complete!

Signed releases

During the release process we generate also the provenance file that is compliant with https://in-toto.io/Statement/v0.1 schema. It contains the information about the github action run that was responsible for the release, but also other metadata about artifacts there were created and their signatures.

This provenance file is signed itself and attached with the signature to the release artifacts. For signing the artifacts we use cosign tool and private key stored as the repository secret. Public key is available in the repository itself in file cosign.pub. This way anybody can verify the origin of arbitrary artifact. In order to regenerate the keys for cosign, one can run cosign generate-key-pair, use some passphrase and update the COSIGN_{PRIVATE,PUBLIC}_KEY & COSIGN_PASSWORD repo secret and also the content of ./cosign.pub file.

All the container images that are produced during the build are also signed with cosign and the signatures are also pushed to the container registries (dockerhub). So that users of k8gb can introduce OPA policy that imposes such verification on our images. These signatures are stored in OCI format under predictable name that can be found using cosign triangulate $IMAGE command. However, cosign verify .. with our public key should be sufficient.

Software bill of materials

For each container image we also create Software bill of materials (SBOM) file + its signature that ends up as part of the release. These files follows this naming pattern: k8gb_{version}_{os}_{arch}.tar.gz.sbom.json and are generated using Syfttool.


Thanks for contributing!