From 40dcbaebb25f70b4ed11cd742359e787ed12d7dc Mon Sep 17 00:00:00 2001
From: Gustavo Alves <112630064+gfariasalves-ionos@users.noreply.github.com>
Date: Tue, 7 May 2024 17:15:11 +0200
Subject: [PATCH] =?UTF-8?q?=F0=9F=93=96=20Extend=20docs=20(#93)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
**What is the purpose of this pull request/Why do we need it?**
**Description of changes:**
This PR updates the documentation, revamping README.md and
development.md, adding CONTRIBUTING.md and SECURITY.md and
style-guide.md (more to come)
**Checklist:**
- [x] Documentation updated
- [x] Includes
[emojis](https://github.com/kubernetes-sigs/kubebuilder-release-tools?tab=readme-ov-file#kubebuilder-project-versioning)
---
CODE_OF_CONDUCT.md | 3 +
CONTRIBUTING.md | 153 ++++++++++++++++++++++++++
LICENSE | 190 ++++++++++++++++++++++++++++++++
README.md | 105 +++++++++---------
SECURITY.md | 16 +++
docs/Development.md | 204 -----------------------------------
docs/LOGO_IONOS_Blue_RGB.png | Bin 0 -> 13385 bytes
docs/development.md | 76 +++++++++++++
docs/local-provider.md | 4 -
docs/quickstart.md | 126 ++++++++++++----------
docs/style-guide.md | 161 +++++++++++++++++++++++++++
11 files changed, 725 insertions(+), 313 deletions(-)
create mode 100644 CODE_OF_CONDUCT.md
create mode 100644 CONTRIBUTING.md
create mode 100644 LICENSE
create mode 100644 SECURITY.md
delete mode 100644 docs/Development.md
create mode 100644 docs/LOGO_IONOS_Blue_RGB.png
create mode 100644 docs/development.md
create mode 100644 docs/style-guide.md
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..f0784dcb
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,3 @@
+# Kubernetes Community Code of Conduct
+
+Please refer to the [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md).
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..a5480393
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,153 @@
+# Contributing to our Cluster API Provider
+
+
+First off, thanks for taking the time to contribute! ❤️
+
+All types of contributions are encouraged and valued. See the
+[Table of Contents](#table-of-contents) for information on how you can help us improve. Please make sure to read the relevant
+section before making your contribution. It will make it a lot easier for the
+maintainers and smooth out the experience for all involved. The community
+looks forward to your contributions. 🎉
+
+> And if you like our work, but just don't have time to contribute, that's
+fine. There are other easy ways to support us and show your
+appreciation, which we would also be very happy about:
+> - Star the project
+> - Tweet about it
+> - Refer to it in your documentation
+> - Mention it at local meetups and tell your friends/colleagues
+
+## Table of Contents
+
+- [Code of Conduct](#code-of-conduct)
+- [I Have a Question](#i-have-a-question)
+- [I Want To Contribute](#i-want-to-contribute)
+- [Reporting Bugs](#reporting-bugs)
+- [Suggesting Enhancements](#suggesting-enhancements)
+- [Your First Contribution](#your-first-contribution)
+
+## Code of Conduct
+
+This project and everyone participating in it is governed by the
+[Kubernetes Code of Conduct](./CODE_OF_CONDUCT.md).
+
+## I Have a Question
+
+> If you want to ask a question, we assume that you have read the
+available [Documentation](./docs/README.md).
+
+Before you ask a question, it is best to search for existing
+[Issues](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues)
+that might help you. In case you have found a suitable issue and still need clarification,
+you can write your question in this issue. It is also advisable to search the internet
+for answers first.
+
+If you then still feel the need to ask a question and need clarification, we recommend
+the following:
+
+- Open an [Issue](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues/new).
+- Provide as much context as you can about what you're running into.
+- Provide project and platform versions (K8s Cluster version, CAPI version etc).
+
+We will get back to you as soon as possible.
+
+## I Want To Contribute
+
+### Legal Notice
+When contributing to this project, you must agree that you have authored 100% of the content,
+that you have the necessary rights to the content and that the content you contribute may
+be provided under the project license.
+
+### Reporting Bugs
+
+#### Before Submitting a Bug Report
+
+A good bug report shouldn't leave others needing to chase you up for more information. Therefore,
+we ask you to investigate carefully, collect information and describe the issue in detail in your
+report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
+
+- Make sure that you are using the latest version.
+- Determine if your bug is really a bug and not an error on your side e.g. using incompatible
+environment components/versions (Make sure that you have read the [documentation](./docs/README.md).
+If you are looking for support, you might want to check [this section](#i-have-a-question)).
+- To see if other users have experienced (and potentially already solved) the same issue you are
+having, check if there is not already a bug report existing for your bug or error in the
+[bug tracker](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues?q=label%3Abug).
+- Also make sure to search the internet (including Stack Overflow) to see if users outside of
+ the GitHub community have discussed the issue.
+- Collect information about the bug:
+- Stack trace (Traceback)
+- OS, Platform and Version (Linux, macOS)
+- Version of your Kubernetes Cluster, kubectl, clusterctl and provider.
+- Possibly your input and the output
+- Can you reliably reproduce the issue?
+
+#### How Do I Submit a Good Bug Report?
+
+> You must never report security related issues, vulnerabilities or bugs including sensitive
+information to the issue tracker, or elsewhere in public. Instead sensitive bugs
+must be handled as described in [the security policy](./SECURITY.md)
+
+We use GitHub issues to track bugs and errors. If you run into an issue with the project:
+
+- Open an [Issue](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues/new).
+(Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about
+a bug yet and not to label the issue.)
+- Explain the behavior you would expect and the actual behavior.
+- Please provide as much context as possible and describe the *reproduction steps*
+that someone else can follow to recreate the issue on their own. This usually includes your code.
+For good bug reports you should isolate the problem and create a reduced test case.
+- Provide the information you collected in the previous section.
+
+Once it's filed:
+
+- The project team will label the issue accordingly.
+- A team member will try to reproduce the issue with your provided steps. If there are no
+reproduction steps or no obvious way to reproduce the issue, the team will ask you for those
+steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not
+be addressed until they are reproduced.
+- If the team is able to reproduce the issue, it will be marked `needs-fix`,
+as well as possibly other tags (such as `critical`), and the issue will be left to be
+[implemented by someone](#your-first-code-contribution).
+
+### Suggesting Enhancements
+
+This section guides you through submitting an enhancement suggestion for
+Cluster API Provider IONOS Cloud, **including completely new features and minor
+improvements to existing functionality**. Following these guidelines will help maintainers
+and the community to understand your suggestion and find related suggestions.
+
+#### Before Submitting an Enhancement
+
+- Make sure that you are using the latest version.
+- Read the [documentation](./docs/README.md) carefully and find out if
+the functionality is already covered, maybe by an individual configuration.
+- Perform a [search](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues)
+to see if the enhancement has already been suggested. If it has, add a comment
+to the existing issue instead of opening a new one.
+- Find out whether your idea fits with the scope and aims of the project. It's up to you to make
+a strong case to convince the project's developers of the merits of this feature. Keep in mind
+that we want features that will be useful to the majority of our users
+and not just a small subset. If you're just targeting a minority of users,
+consider writing an add-on/plugin library.
+
+#### How Do I Submit a Good Enhancement Suggestion?
+
+Enhancement suggestions are tracked as [GitHub issues](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues).
+
+- Use a **clear and descriptive title** for the issue to identify the suggestion.
+- Provide a **step-by-step description of the suggested enhancement** in as many
+details as possible.
+- **Describe the current behavior** and **explain which behavior you expected to see
+instead** and why. At this point you can also tell which alternatives do not work for you.
+- **Explain why this enhancement would be useful** to most Cluster API Provider IONOS Cloud users.
+You may also want to point out the other projects that solved it better and which could serve as inspiration.
+
+### Your First Contribution
+
+Check how to set up your development environment, our style guide and how to create a pull
+request at (./docs/Development.md)
+
+## Attribution
+This guide is based on the [contributing-gen](https://github.com/bttger/contributing-gen)
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..acee851f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,190 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright 2023-2024 IONOS Cloud.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
index 1343dfe4..c7f0c939 100644
--- a/README.md
+++ b/README.md
@@ -1,73 +1,80 @@
-# Kubernetes Cluster API Provider for IONOS Cloud - CAPIC
+# Kubernetes Cluster API Provider IONOS Cloud
-[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ionos-cloud_cluster-api-provider-ionoscloud&metric=alert_status&token=61ea2f753f2b2a3ed9a2cf966248fdd57d7f6ebd)](https://sonarcloud.io/summary/new_code?id=ionos-cloud_cluster-api-provider-ionoscloud)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-## Table of Contents
+Kubernetes-native declarative infrastructure for IONOS Cloud.
----
+## What is the Cluster API Provider IONOS Cloud
-- [Overview](#overview)
-- [Documentation](#documentation)
-- [Launching a Kubernetes cluster on IONOS Cloud](#launching-a-kubernetes-cluster-on-ionos-cloud)
-- [Features](#features)
-- [Maintainers](#maintainers)
-- [License](#license)
-
+The Cluster API Provider IONOS Cloud makes declarative provisioning of multiple Kubernetes clusters through Cluster API on IONOS Cloud infrastructure possible.
-## Overview
+[Cluster API][cluster_api] is a Kubernetes sub-project focused on providing declarative APIs and tooling to simplify provisioning, upgrading, and operating multiple Kubernetes clusters.
----
+Started by the Kubernetes Special Interest Group (SIG) Cluster Lifecycle, the Cluster API project uses Kubernetes-style APIs and patterns to automate cluster lifecycle management for platform operators. The supporting infrastructure, like virtual machines, networks, load balancers, and VPCs, as well as the Kubernetes cluster configuration are all defined in the same way that application developers operate deploying and managing their workloads. This enables consistent and repeatable cluster deployments across a wide variety of infrastructure environments.
-The [Cluster API](https://github.com/kubernetes-sigs/cluster-api) brings declarative, Kubernetes-style APIs to cluster creation, configuration and management.
+## Quick Start
-## Documentation
-
----
+Check out the [Cluster API Quick Start](docs/quickstart.md) to create your first Kubernetes cluster.
-Documentation can be found in the ./docs folder.
+
-## Launching a Kubernetes cluster on IONOS Cloud
+## Compatibility
----
+### Cluster API Versions (TODO)
-Check out the [quickstart guide](./docs/quickstart.md) to get started with launching a cluster on IONOS Cloud.
+### Kubernetes Versions (TODO)
-## Features
+The IONOS Cloud provider is able to install and manage the [versions of Kubernetes supported by the Cluster API (CAPI) project](https://cluster-api.sigs.k8s.io/reference/versions.html#supported-kubernetes-versions).
----
+For more information on Kubernetes version support, see the [Cluster API book](https://cluster-api.sigs.k8s.io/reference/versions.html).
-* Native Kubernetes manifests and API.
-* Manages the bootstrapping of LANs, Failover Groups and VMs on IONOS Cloud.
-* Deploys Kubernetes control planes into provided virtual data center in IONOS Cloud.
-* Doesn't use SSH for bootstrapping nodes.
-* Installs only the minimal components to bootstrap a control plane and workers.
-* Uses IPv6 by default.
-
-## Maintainers
+## Documentation
-| Username |
-|-----------------------|
-| @piepmatz |
-| @gfariasalves-ionos |
-| @lubedacht |
-| @wikkyk |
+Documentation can be found in the `/docs` directory, and the [index is here](docs/README.md).
+## Getting involved and contributing
-## License
+Are you interested in contributing to cluster-api-provider-ionoscloud? We, the
+maintainers and the community, would love your suggestions, contributions, and help!
+Also, the maintainers can be contacted at any time to learn more about how to get
+involved.
-Copyright 2024 IONOS Cloud.
+To set up for your environment, check out the [development guide](docs/development.md).
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+In the interest of getting more new people involved, we tag issues with
+[`good first issue`][good_first_issue].
+These are typically issues that have smaller scope but are good ways to start
+to get acquainted with the codebase.
- http://www.apache.org/licenses/LICENSE-2.0
+We also encourage ALL active community participants to act as if they are
+maintainers, even if you don't have "official" write permissions. This is a
+community effort, we are here to serve the Kubernetes community. If you have an
+active interest and you want to get involved, you have real power! Don't assume
+that the only people who can get things done around here are the "maintainers".
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+
+
+[good_first_issue]: https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22
+[bug_report]: https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/issues/new?template=bug_report.md
+[feature_request]: https://github.com/kubernetes-sigs/cluster-api-provider-ionoscloud/issues/new?template=feature_request.md
+[cluster_api]: https://github.com/ionos-cloud/cluster-api
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..c5474ed9
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,16 @@
+# Security Policy
+
+## Supported Versions
+
+| Version | Supported |
+| ------- | ------------------ |
+| v0.1.0 | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+At IONOS Cloud, we take security seriously and value the contributions of security researchers and the broader community to keep our systems secure. If you believe you have found a security vulnerability or issue within our provider, please report it to us promptly. We appreciate your help in disclosing the issue responsibly.
+
+To report a security issue, please [open a draft security advisory](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/security/advisories/new). We kindly request that you do not disclose the issue publicly until we have had an opportunity to address it.
+
+When reporting, please provide detailed information about the nature of the issue so that we can address it as quickly as possible. We aim to respond to security vulnerability reports within two workdays and will keep you informed of our progress.
+
diff --git a/docs/Development.md b/docs/Development.md
deleted file mode 100644
index b407ee8a..00000000
--- a/docs/Development.md
+++ /dev/null
@@ -1,204 +0,0 @@
-### Temporary development documentation
-
-## Note
-
-This document contains helpful development information and hacks,
-which should help you to get started with the
-
-## Scaffolding
-
-Brief summary of commands, which were used to scaffold the project
-
-### Initialization
-
-Init the project
-
-```bash
-kubebuilder init \
---domain cluster.x-k8s.io \
---repo github.com/ionos-cloud/cluster-api-provider-ionoscloud \
---project-name cluster-api-provider-ionoscloud
-```
-
-### Create API types
-
-We create an infrastructure provider. Therefore, we need to follow the naming conventions.
-
-[Resource Naming](https://cluster-api.sigs.k8s.io/developer/providers/implementers-guide/naming.html?highlight=cluster.x-k8s.io#resource-naming)
-
-Our group would be `infrastructure` to get `infrastructure.cluster.x-k8s.io` as group.
-Initial version will be v1alpha1
-
-```bash
-# Create the cluster resource
-
-kubebuilder create api \
---resource \
---controller \
---group infrastructure \
---version v1alpha1 \
---kind IonosCloudCluster \
---namespaced
-
-# Create the machine resource
-
-kubebuilder create api \
---resource \
---controller \
---group infrastructure \
---version v1alpha1 \
---kind IonosCloudMachine \
---namespaced
-
-```
-
-### Setup local test environment
-
-TODO: convert steps to proper documentation
-
-Steps:
-1. make sure to have folder structure
-../
-/cluster-api
-/cluster-api-provider-ionoscloud
-2. tilt settings file
-3. install kind
-4. install tilt
-5. create kind cluster
-6. tilt up
-
-### Make sure our api resources implement the contracts
-
-[Cluster Contract](https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster#infrastructure-provider)
-
-[Machine Contract](https://cluster-api.sigs.k8s.io/developer/architecture/controllers/machine#infrastructure-provider)
-
-
-TODO(lubedacht): Add proper cluster-api development setup guide using Tilt.
-
-## Getting Started
-You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster.
-**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).
-
-### Running on the cluster
-1. Install Instances of Custom Resources:
-
-```sh
-kubectl apply -k config/samples/
-```
-
-2. Build and push your image to the location specified by `IMG`:
-
-```sh
-make docker-build docker-push IMG=/cluster-api-provider-ionoscloud:tag
-```
-
-3. Deploy the controller to the cluster with the image specified by `IMG`:
-
-```sh
-make deploy IMG=/cluster-api-provider-ionoscloud:tag
-```
-
-### Uninstall CRDs
-To delete the CRDs from the cluster:
-
-```sh
-make uninstall
-```
-
-### Undeploy controller
-UnDeploy the controller from the cluster:
-
-```sh
-make undeploy
-```
-
-## Contributing
-// TODO(user): Add detailed information on how you would like others to contribute to this project
-
-### How it works
-This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/).
-
-It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/),
-which provide a reconcile function responsible for synchronizing resources until the desired state is reached on the cluster.
-
-### Test It Out
-1. Install the CRDs into the cluster:
-
-```sh
-make install
-```
-
-2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running):
-
-```sh
-make run
-```
-
-**NOTE:** You can also run this in one step by running: `make install run`
-
-### Modifying the API definitions
-If you are editing the API definitions, generate the manifests such as CRs or CRDs using:
-
-```sh
-make manifests
-```
-
-**NOTE:** Run `make --help` for more information on all potential `make` targets
-
-More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
-
-### Running Tilt
-- Create a directory and cd into it
-- Clone [cluster-api](https://github.com/kubernetes-sigs/cluster-api)
-- Clone [cluster-api-provider-ionoscloud](https://github.com/ionos-cloud/cluster-api-provider-ionoscloud)
-
-- You should now have a directory containing the following git repositories:
-```
-./cluster-api
-./cluster-api-provider-ionoscloud
-```
-
-- Change directory to cluster-api: `cd cluster-api`. This directory is the working directory for Tilt.
-- Create a file called `tilt-settings.json` with the following contents:
-
-```json
-{
- "default_registry": "ghcr.io/ionos-cloud",
- "provider_repos": ["../cluster-api-provider-ionoscloud/"],
- "enable_providers": ["ionoscloud", "kubeadm-bootstrap", "kubeadm-control-plane"],
- "allowed_contexts": ["minikube"],
- "kustomize_substitutions": {},
- "extra_args": {
- "ionoscloud": ["--v=4"]
- }
-}
-```
-
-This file instructs Tilt to use the cluster-api-provider-ionoscloud. `allowed_contexts` is used to add
-allowed clusters other than kind (which is always implicitly enabled).
-
-- If you don't have a cluster, create a new kind cluster:
-```
-kind create cluster --name capi-test
-```
-- cluster-api-provider-ionoscloud uses environment variables to connect to the IONOS Cloud API. These need to be set in the shell which spawns Tilt.
- Tilt will pass these to the respective Kubernetes pods created. All variables are documented in `../cluster-api-provider-ionoscloud/envfile.example`.
- Copy `../cluster-api-provider-ionoscloud/envfile.example` to `../cluster-api-provider-ionoscloud/envfile` and make changes pertaining to your configuration.
- For documentation on environment variables, see [usage](Usage.md#environment-variables)
-
-- If you already have a kind cluster with a name that is different to `kind-capi-test`, add this line to `../cluster-api-provider-ionoscloud/envfile`:
-```
-export CAPI_KIND_CLUSTER_NAME=
-```
-
-- Start Tilt with the following command (with CWD still being ./cluster-api):
-```
-. ../cluster-api-provider-ionoscloud/envfile && tilt up
-```
-
-Press the **space** key to open the Tilt web interface in your browser. Check that all resources turn green and there are no warnings.
-You can click on (Tiltfile) to see all the resources.
-
-> **Congratulations** you now have CAPIC running via Tilt. If you make any code changes you should see that CAPIC is automatically rebuilt.
-For help deploying your first cluster with CAPIC, see [usage](Usage.md).
diff --git a/docs/LOGO_IONOS_Blue_RGB.png b/docs/LOGO_IONOS_Blue_RGB.png
new file mode 100644
index 0000000000000000000000000000000000000000..8dfae8890378fdeebd87a1d2e81a9da1b73cbf60
GIT binary patch
literal 13385
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
literal 0
HcmV?d00001
diff --git a/docs/development.md b/docs/development.md
new file mode 100644
index 00000000..fa1ce37d
--- /dev/null
+++ b/docs/development.md
@@ -0,0 +1,76 @@
+# Developing Cluster API Provider IONOS Cloud
+
+This document describes how to use `kind` and `Tilt` for a simplified workflow that offers easy deployments and rapid iterative builds.
+
+## Prerequisites
+
+- Docker: v19.03 or newer
+- kind: v0.22.0 or newer
+- Tilt: v0.30.8 or newer
+- kustomize: provided via make kustomize
+- envsubst: provided via make envsubst
+- helm: v3.7.1 or newer
+- Clone the Cluster API repository locally
+- The provider repo
+
+## Getting started
+
+### Create a kind cluster
+
+A script to create a `kind` cluster along with a local Docker registry and the correct mounts to run CAPD is included in the cluster-api repo `hack/` folder.
+
+To create a pre-configured cluster run:
+
+```sh
+./hack/kind-install-for-capd.sh
+```
+You can see the status of the cluster with:
+
+```sh
+kubectl cluster-info --context kind-capi-test
+```
+
+### Create a tilt-settings file
+
+Create the tilt settings file `tilt-settings.yaml` in the `cluster-api` folder:
+
+```yaml
+default_registry: ghcr.io/ionos-cloud
+provider_repos:
+- ../cluster-api-provider-ionoscloud # path to the provider repo
+enable_providers:
+- ionoscloud
+- kubeadm-bootstrap
+- kubeadm-control-plane
+allowed_contexts:
+- minikube
+kustomize_substitutions: {}
+extra_args:
+ ionoscloud:
+ - "--v=4"
+```
+
+Note: You're developing the provider, so you might as well want to debug it. For this you might want to add the following to the file above:
+
+```yaml
+debug:
+ ionoscloud:
+ continue: false # waits for the user to connect to the debugger
+ port: 30000 # port where the debugger will be exposed
+```
+
+## Create a kind cluster and run Tilt!
+
+To create a pre-configured kind cluster (if you have not already done so) and launch your development environment, you need first of all to copy the [envfile.example](../envfile.example) file in the provider repository and replace the values accordingly.
+
+Then, run the following in the cluster-api directory:
+
+```sh
+. ../cluster-api-provider-ionoscloud/envfile && make tilt-up
+```
+
+This will open the command-line HUD as well as a web browser interface. You can monitor Tilt’s status in either location. After a brief amount of time, you should have a running development environment, and you should now be able to create a cluster. There are example worker cluster configs available. These can be customized for your specific needs.
+
+## Notes
+
+This document was adapted from the [Cluster API book](https://cluster-api.sigs.k8s.io/developer/tilt). Please refer to it if you want to use other options with Tilt.
\ No newline at end of file
diff --git a/docs/local-provider.md b/docs/local-provider.md
index cf87a221..73d7d095 100644
--- a/docs/local-provider.md
+++ b/docs/local-provider.md
@@ -2,8 +2,6 @@
## Why?
----
-
You might want to use `clusterctl init` to install your provider. If you are in your development phase,
you cannot yet make use of that, as per default `clusterctl` will only try to find providers hardcoded in its source code.
Therefore, you will have to write a configuration file which will point `clusterctl` to the URLs
@@ -19,8 +17,6 @@ using `clusterctl init`
## Guide
----
-
In order for clusterctl to make use of local providers, we need some kind of contract files, which we have to make available. These are:
`metadata.yaml` and `*-components.yaml`
diff --git a/docs/quickstart.md b/docs/quickstart.md
index 61bc3966..c6ffb8d0 100644
--- a/docs/quickstart.md
+++ b/docs/quickstart.md
@@ -4,60 +4,39 @@ This is a guide on how to use the Cluster API Provider for IONOS Cloud (CAPIC) t
on IONOS Cloud. To learn more about the Cluster API, please refer
to the official [Cluster API book](https://cluster-api.sigs.k8s.io/).
-## Table of Contents
+## Dependencies
-* [Usage](#usage)
- * [Prerequisites](#prerequisites)
- * [Quickstart](#quickstart)
- * [Case 1: Using a local provider](#case-1-using-a-local-provider)
- * [Case 2: The provider is already available in clusterctl](#case-2-the-provider-is-already-available-in-clusterctl)
- * [Configuring the management cluster](#configuring-the-management-cluster)
- * [Environment variables](#environment-variables)
- * [Create a workload cluster](#create-a-workload-cluster)
- * [Next Steps](#next-steps)
- * [Troubleshooting](#troubleshooting)
- * [Useful Resources](#useful-resources)
+In order to deploy a K8s cluster with CAPIC, you require the following:
-## Prerequisites
+* A machine image, containing pre-installed, matching versions of `kubeadm` and `kubelet`. The machine image can be built with [image-builder](https://github.com/kubernetes-sigs/image-builder) and needs to be available at the
+location where the machine will be created on. For more information, [check the custom image guide](custom-image.md).
-Before you can use CAPIC, you need to have the following prerequisites:
+* `clusterctl`, which you can download from Cluster API (CAPI) [releases](https://github.com/kubernetes-sigs/cluster-api/releases) on GitHub.
-* A Kubernetes cluster which can run the required providers for CAPIC.
-* An image, which is used to create the Kubernetes cluster. This image has to be available in the IONOS Cloud location
- of the datacenter where you want to create the Kubernetes cluster.
- * The image can be built via [image-builder](https://github.com/kubernetes-sigs/image-builder)
- * It must be built as a raw QEMU image. Refer to the [custom image](./custom-image.md) documentation for more information.
-* `clusterctl`, which can be installed via the [official documentation](https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl).
-* A datacenter in IONOS Cloud where you want to create the Kubernetes cluster.
+* A Kubernetes cluster for running your CAPIC controller.
-## Quickstart
+### Initialize the management cluster
-In order to install Cluster API Provider for IONOS Cloud (CAPIC), you need to have a Kubernetes cluster up and running,
-and `clusterctl` installed.
+Before creating a Kubernetes cluster on IONOS Cloud, you must initialize a
+[management cluster](https://cluster-api.sigs.k8s.io/user/concepts#management-cluster) where CAPI and CAPIC controllers run.
-### Case 1: Using a local provider
+First, we need to add the IONOS Cloud provider to clusterctl config file `~/.cluster-api/clusterctl.yaml`:
-If the provider is not yet added to the list of providers in `clusterctl`, you can bootstrap the management cluster
-using a local provider. Refer to [local provider](./local-provider.md) for more information.
-
-### Case 2: The provider is already available in clusterctl
-
-In this case you can simply follow the steps below. Make sure you are using a version of `clusterctl` which
-supports the `IONOS Cloud provider`.
-
-### Configuring the management cluster
-
-Before you can create a Kubernetes cluster on IONOS Cloud, you need to configure the management cluster.
-Currently, the controller has no need of any special configuration, so you can just run the following command:
+```yaml
+providers:
+- name: ionoscloud
+ url: https://github.com/ionos-cloud/cluster-api-provider-ionoscloud/releases/latest/infrastructure-components.yaml
+ type: InfrastructureProvider
+```
```sh
clusterctl init --infrastructure=ionoscloud
```
-
### Environment variables
CAPIC requires several environment variables to be set in order to create a Kubernetes cluster on IONOS Cloud.
+ They can be exported or saved inside the clusterctl config file at `~/.cluster-api/clusterctl.yaml`
```env
## -- Cloud-specific environment variables -- ##
@@ -106,53 +85,88 @@ stringData:
-----END CERTIFICATE-----
```
-The `apiURL` field is optional and defaults to `https://api.ionos.com/cloudapi/v6` if no value was provided.
+Notes:
-The `caBundle` field is optional. It can be used to provide a custom PEM-encoded CA bundle used to validate the
+- The `apiURL` field is optional and defaults to `https://api.ionos.com/cloudapi/v6` if no value was provided.
+- The `caBundle` field is optional. It can be used to provide a custom PEM-encoded CA bundle used to validate the
IONOS Cloud API TLS certificate. If unset, the system's root CA set is used. In case of our provided Dockerfile that
would be Debian 12's `ca-certificates` package.
### Create a workload cluster
-In order to create a new cluster, you need to generate a cluster manifest.
+In order to create a new cluster, you need to generate a cluster manifest with `clusterctl` and then apply it with `kubectl`.
```sh
-# Make sure you have the required environment variables set
-$ source envfile
# Generate a cluster manifest
-$ clusterctl generate cluster ionos-quickstart \
+clusterctl generate cluster ionos-quickstart \
--infrastructure ionoscloud \
--kubernetes-version v1.29.2 \
--control-plane-machine-count 3 \
--worker-machine-count 3 > cluster.yaml
# Create the workload cluster by applying the manifest
-$ kubectl apply -f cluster.yaml
+kubectl apply -f cluster.yaml
```
-### Next steps
+### Check the status of the cluster
-TODO
+```sh
+clusterctl describe cluster ionos-quickstart
+```
-### Observability
+Wait until the cluster is ready. This can take a few minutes.
-#### Diagnostics
+### Access the cluster
-Access to metrics is secured by default. Before using it, it is necessary to create appropriate roles and role bindings.
-For more information, refer to [Cluster API documentation](https://main.cluster-api.sigs.k8s.io/tasks/diagnostics).
+You can use the following command to get the kubeconfig:
-### Troubleshooting
+```sh
+clusterctl get kubeconfig ionos-quickstart > ionos-quickstart.kubeconfig
+```
+If you do not have CNI yet, you can use the following command to install a CNI:
-TODO
+```sh
+KUBECONFIG=ionos-quickstart.kubeconfig kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
+```
+After that you should see your nodes become ready:
+```sh
+KUBECONFIG=ionos-quickstart.kubeconfig kubectl get nodes
+```
-### Useful resources
+### Installing a CNI
----
+TODO(gfariasalves): Add instructions about installing a CNI or available flavours
+
+### Cleaning a cluster
+
+```sh
+kubectl delete cluster ionos-quickstart
+```
+
+### Custom Templates
+
+If you need anything specific that requires a more complex setup, we recommend to use custom templates:
+
+```sh
+clusterctl generate custom-cluster ionos-quickstart \
+ --kubernetes-version v1.27.8 \
+ --control-plane-machine-count 1 \
+ --worker-machine-count 3 \
+ --from ~/workspace/custom-cluster-template.yaml > custom-cluster.yaml
+```
+
+### Observability
+
+#### Diagnostics
+
+Access to metrics is secured by default. Before using it, it is necessary to create appropriate roles and role bindings.
+For more information, refer to [Cluster API documentation](https://main.cluster-api.sigs.k8s.io/tasks/diagnostics).
+
+### Useful resources
* [Cluster API Book](https://cluster-api.sigs.k8s.io/)
* [Cloud API Docs](https://api.ionos.com/docs/cloud/v6/)
* [IONOS Cloud Docs](https://docs.ionos.com/cloud)
* [IPv6 Documentation](https://docs.ionos.com/cloud/network-services/ipv6)
-
diff --git a/docs/style-guide.md b/docs/style-guide.md
new file mode 100644
index 00000000..1b33747d
--- /dev/null
+++ b/docs/style-guide.md
@@ -0,0 +1,161 @@
+# Coding guidelines
+
+This page collects common comments made during reviews. This is a laundry list of common mistakes, not a comprehensive style guide.
+
+## Previous work
+
+Sticking to the following three guidelines will greatly increase your reviewers’ happiness levels:
+
+- https://go.dev/doc/effective_go
+- https://tip.golang.org/doc/comment
+- https://github.com/golang/go/wiki/CodeReviewComments
+
+In addition to that, we compiled a list of a few more things that are quite common.
+
+
+## TL;DR
+
+- Be consistent, concise and check your own work.
+- “TODO” and “NOTE” comments should have an issue ID.
+- Spelling and grammars matters.
+- PRs must be squashed before merging and should have a short and long description separated by an empty newline.
+- Use correct variable and import alias names.
+- Wrap errors with fmt.Errorf(“...%w”, err) and compare them via errors.Is.
+- Contexts must be passed down the call stack and should be the first argument.
+- Do not use context.Background() or context.TODO(), except in tests.
+- Check Go Docs and comments for validity even in unchanged but affected places.
+- All public functions must be tested
+- Tests must run with enabled race detection.
+
+## General non-code stuff
+
+- Consistency, consistency, consistency. This applies almost everywhere.
+- Review your code yourself before you ask someone else to do it.
+- Check what you are about to commit.
+- The reviewer opens a comment, and it's the reviewer resolving the comment. You can answer if you have questions or disagree or want to discuss things.
+- Avoid changes not related to your ticket. Only do those flybys if they are really absolutely nothing a reviewer could complain about. Typos are usually ok, but everyone likes a clear focus instead of discussing stuff that's actually off-topic.
+- Don’t force-push your git branch after someone started reviewing it. Changing the history makes it harder for a reviewer to find the exact diff, e.g. since the reviewer had a look the last time.
+- Pull requests that are not meant to be reviewed or are a work in progress SHOULD be set to “draft”.
+- A pull request’s single commits MUST be squashed via GitHub when merging. Also check the guidelines for commit messages below.
+
+## General code stuff
+
+- Consistency, it also applies here.
+- When leaving TODO comments in the code, make sure you add your name to it, e.g.
+ ```go
+ func foo() {
+ // TODO(emustermann, this should be done later)
+ }
+ ```
+- Longer comments that are more than just normal code comments SHOULD be marked as a NOTE, again with the name:
+ ```go
+ // NOTE(emustermann): Lorem ipsum dolor sit amet, consetetur
+ // sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore
+ // magna aliquyam erat, sed diam voluptua.
+ // At vero eos et accusam et justo duo dolores et ea rebum.
+ // Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+ ```
+- Keep interfaces small. This applies to Golang interfaces themselves, but also to a package's and type's exported functions. Same for variables and constants.
+
+- If in doubt, use a pointer (see go-code-reviews).
+
+- Infrastructure types attributes, unless necessary, should not be pointers (e.g. use `string` instead of `*string`)
+
+- Use constructors to initialize structs if they are more convenient, e.gi.e. less fields required, sets defaults, etc.
+
+- Group struct fields by public/private and purpose, e.g. a mutex stays with the objects it protects.
+
+- If you add a field to a struct with alphabetically sorted fields, keep the fields sorted.
+
+## Commit messages
+
+> (OpenStack has compiled some best-practices. For inspiration: https://wiki.openstack.org/wiki/GitCommitMessages)
+
+The following requirements are only applicable to your final squashed commit. It does not apply to your single commits in your development branch.
+
+- The commit message proposed by GitHub just contains all single commits’ messages and is often too verbose, outdated and not helpful.
+- Your commit message SHOULD adhere to the following structure:
+ - Provide a brief description of the change in the first line. This does not include the ticket ID.
+ - Insert a single blank line after the first line.
+ - Provide a detailed description of the change in the following lines, breaking paragraphs where needed.
+ - The first line is limited to 50 characters and does not end with a period.
+ - Subsequent lines are wrapped at 72 characters.
+ - Your commit references the feature/bug it implements/fixes, e.g. by adding a last paragraph with “Implements: ” or “Fixes: ”. There can be multiple of those ticket references in that paragraph. Other keywords include “Relates-To”.
+
+## Naming conventions
+
+- Use camel-case with capital letters for acronyms, e.g. HTTP, API, etc.
+- Import names and aliases SHOULD be precise. v1 isn't. E.g. in the context of K8s, we use corev1, metav1, appsv1 etc.
+- Be consistent here, too: Match parameters and type names at package level, e.g. single name for a client parameter across different functions. Match import aliases across files and preferably across the whole project. The importas linter can be used to enforce this.
+- Use meaningful names. This is not C. But also not Java. Getters should not be prefixed with Get, see effective_go.
+- Prefer “node pool” over “nodepool”; "Data center" is a special case: Variables should have it as one word `datacenter` but comments should have it as two words `// data center`.
+- Package names SHOULD be in singular not plural form. E.g. middleware instead of middlewares. From a package consumer point of view it can also be better to have distinct subpackages in middleware instead of having a collection of middlewares that have nothing in common (besides being a middleware). However, no need to change plural names created by code generation tools like kubebuilder that don’t provide configuration options. We don’t want to fight our tools.
+
+## Spelling & grammar
+
+- Aim to write good English. There are tools online that can help you with this.
+- Inside comments, write things the way they're spelled/stylized. Ionos Cloud -> IONOS Cloud; CoreDns -> CoreDNS; Ip -> IP. A special case is "identifier": here we always use ID.
+
+
+## Errors
+
+- You SHOULD wrap errors if there is additional useful information.
+- Error variables SHOULD begin with Err and error types SHOULD end with Error.
+- Compare errors for equality with errors.Is. (which is different from errors.As )
+
+## Godoc
+
+- When you have godocs for an interface methods AND its implementation(s), changing the godocs in one place might require changes to the other place(s), too.
+- Exported stuff needs godocs unless they implement a built-in interface, e.g. error or are getters or setters.
+Context
+- Functions that accept a context MUST pass it down the call stack instead of using context.Background() or context.TODO(), unless there is a good reason to do so which MUST then be added as comment.
+- If a context is not available, change the parent function signature to accept one and pass it on. Do not use context.Background() or context.TODO().
+
+## Refactoring
+
+- When you rename a function, you might also need to rename corresponding tests.
+- Use your editor "Search and Replace" functionality. Finding all the places manually has proven to be error-prone. Check that you didn't replace more than intended.
+- When moving stuff around, make sure that code comments stay valid and close to the code they refer to.
+
+## Testing
+
+- All public functions of a package SHOULD be tested even if they are trivial.
+- If you add or change logic, you probably also need to touch the unit tests.
+- No need to retest stuff in integration tests that were already covered by unit tests.
+- Code coverage is good, but it is not required to get it to 100%. Cover the important code paths. Simple if err != nil { return fmt.Errorf("...: %w", err) } occurrences don’t need to be covered, we have the nilerr linter for that.
+- Tests MUST run with enabled race detection.
+- Your table-driven test cases SHOULD NOT share any lines, so please avoid }, {
+- Don’t overcomplicate table-driven tests. If the setup becomes increasingly complex consider refactoring instead of extending the test. Each control flow statement in the test body increases the probability that a separate test function should be implemented.
+- If you need a context in tests, use context.Background().
+- When mocking calls, try to be precise. mock.Anything is fine for complicated data structures we don't care too much about (e.g. contexts), but don't overuse it.
+- github.com/stretchr/testify has lots of convenient functions. Use them. There’s more than Equal(). Same goes for gomega/ginkgo. An IDE might help you find those helpers.
+- Use testify’s require instead of assert if all assertions afterwards would fail anyway and don't provide more insights for debugging the test. Test setup code (like writing files or initializing data) MUST use require instead of ignoring errors.
+- Tests that do repetitive setup SHOULD use the suite package.
+- If your test suite only has a single test, then there might be no reason to use a suite at all.
+- Tests SHOULD make use of t.Cleanup() for tear down steps. It is not widely used yet, but we should gradually migrate.
+- Tests SHOULD use t.Parallel() ONLY when the tested code does not depend on unlocked global state like function variables or singletons. Always check if imported code depends on global state and is safe to be used concurrently. testify’s suites have problems with running tests in parallel: https://github.com/stretchr/testify/issues/187
+- Helper test functions SHOULD use t.Helper()
+- Create a variable at the appropriate scope if you find yourself initializing one over and over.
+- It’s okay to drop the error for “mock” functions, e.g. wrapping io.Writer.Write. Just assign it to the _ variable.
+
+## Debugging
+
+- Rather use the debugger than instrumenting your code with fmt.Println calls.
+
+## CRDs, controllers, operators
+
+- Optional fields in CRDs SHOULD also use omitempty in their json struct tags.
+- When writing kubebuilder RBAC markers think about whether you use a caching client. If so, each GET will also issue a LIST and a WATCH.
+
+
+## Logging
+
+- Use lowerCamelCase keys for log fields, e.g: requestID, durationMS.
+- Logging keys set by WithValues should not persist past their intended use/scope, e.g. continuing to use a request body.
+- Logging errors SHOULD happen with a format that will show a potential corresponding stack trace, e.g. %+v.
+- Use the proper log level:
+ - Trace: Information provided as this level is only relevant for the developer. There is no rule for a proper amount of log messages, but it should not replace your debugger during development. It shall help to understand the program flow without a debugger in a production environment.
+ - Debug: Information that is diagnostically helpful to more people than just developers (IT, sysadmins, etc.).
+ - Info: Generally useful information to log (service start/stop, configuration assumptions, etc). This is the standard log level and must keep a good signal-to-noise ratio.
+ - Warning: Not an error but likely more important than an informational event. This could for example be a deprecation warning.
+ - Error: Any error, regardless if an operation failed, or the service recovered a panic. An error might require manual work to fix, or indicate a transient error, that recovers automatically. But it still indicates non-normal program flow.