Add package design goals to CLI package documentation

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-08-08 15:18:36 +02:00 committed by Daniel Weiße
parent 946942ba68
commit 99c579b45a
10 changed files with 56 additions and 135 deletions

View File

@ -1,121 +0,0 @@
# Constellation CLI design guide
This document aims to outline the design principals behind the CLI code and packages.
It should be consulted by developers when making changes to the code of packages in [`cli/internal/`](./internal/).
## Basic layout
[`cli/`](./) consists of 2 packages, [`cli/cmd/`](./cmd/), and [`cli/internal/`](./internal/), and a [`main.go`](./main.go), which serves as the entrypoint for the CLI.
No new packages or files should be added to this base directory.
[`cli/cmd/`](./cmd/) defines the root command of the CLI. Any changes concerning the root command, or additions like persistent flags (flags that can be accessed by all subcommands) should be added here.
TODO: Discuss: Root command could be added to `cli/internal/cmd/`
[`cli/internal/`](./internal/) holds the actual logic of the CLI, and will be discussed in detail in the following sections.
The code is kept as internal packages to avoid accidentally exposing non public API logic of the CLI to other packages of Constellation.
Any shared code should instead go into the global [`internal/` package](../internal/).
## The internal package
[`cli/internal/`](./internal/) implements logic of the CLI and is split into multiple distinct packages.
Each package should aim to implement a specific functionality. Multi purposes packages should be avoided.
The following packages are listed and explained in alphabetical order. New packages should be added here when they are created.
### [`cloudcmd`](./internal/cloudcmd/)
This package focuses on the interaction with the cloud provider.
It separates the cloud provider specific code from the rest of the CLI, and
provides a common interface for all cloud providers.
Exported functions defined here should be cloud provider agnostic, meaning there should be no functions for specific CSPs.
Rather the `cloudcmd` package should declare functions that take a `cloudprovier.Provider` as argument,
perform CSP specific logic, and return a universally usable result.
It is used by the [`cmd` package](#cmd) to handle creation of cloud resources and other CSP specific interactions.
### [`clusterid`](./internal/clusterid)
Defines the structure of the Constellation cluster ID file.
Logic in this package should be kept minimal.
### [`cmd`](./internal/cmd)
Defines the commands of the CLI.
Logic should be kept to input/output parsing whenever possible.
Any more complex code should usually be implemented in one of the other CLI packages.
The code here should be kept as cloud provider agnostic as possible.
Any CSP specific tasks should be handled by [`cloudcmd`](#cloudcmd).
All filepaths handled by the CLI code should originate from here.
Common filepaths are defined as constants in [`internal/constants`](../internal/constants/).
To generate workspace correct filepaths for printing, use the functions from [`workspace.go`](./internal/cmd/workspace.go) // TODO: Discuss if we should move this to its own package
### [`featureset`](./internal/featureset)
`featureset` defines feature gate constants for the CLI and should not implement any logic.
### [`helm`](./internal/helm)
Helm is used to manage Kubernetes deployments of a Constellation cluster.
The package implements functionality to install, update, and manage Helm charts.
The charts themselves are embedded in a built CLI binary, and values are dynamically updated depending on configuration.
The charts can be found in [`cli/internal/helm/charts/`](./internal/helm/charts/).
Helm logic should not be implemented outside this package.
All values loading, parsing, installing, uninstalling, and updating of charts should be implemented here.
As such, the number of exported functions should be kept minimal.
### [`iamid`](./internal/iamid)
Defines the structure of the IAM service account file.
TODO: Discuss if this should be renamed.
The cluster ID file was named as such because it contains the cluster ID.
A similar thing is not the case for this file.
TODO: Discuss if this should be moved.
Having this as a standalone package seems slightly weird, since it contains just CSP specific information generated by Terraform.
Additionally the content of this struct are never written as a file, the output simply printed to the user, or written to their config.
Maybe restructuring this as a return value for the IAM cloud creator would be a better fit.
### [`kubernetes`](./internal/kubernetes)
For fetching status information updating resources in Kubernetes not directly managed by Helm,
the CLI needs to interact with the Kubernetes API directly.
This functionality is implemented in the `kubernetes` package.
The package should be used for:
* Fetching status information about the cluster
* Creating, deleting, or migrating resources not managed by Helm
The package should not be used for anything that doesn't just require the Kubernetes API.
For example, Terraform and Helm actions should not be accessed by this package.
### [`libvirt`](./internal/libvirt)
Constellation uses libvirt to run clusters on local hardware.
To enable easy deployment across different Linux distributions, the CLI can deploy libvirt inside a Docker container.
The required files and Go code to start the container can be found in [`cli/internal/libvirt/`](./internal/libvirt/).
The code in this package should be kept minimal, and likely won't need to be changed unless we do a major refactoring of our QEMU/libvirt installation.
### [`terraform`](./internal/terraform)
Terraform is used to create cloud resources and IAM resources required for Constellation clusters.
The package implements functionality to create, update, delete, and view said resources.
The Terraform files are embedded in a built CLI binary, and variables are dynamically update depending on configuration.
The files can be found in [`cli/internal/terraform/terraform/`](./internal/terraform/terraform/).
Functions of this package should be kept mostly cloud agnostic (There should be no "CreateAzureCluster" function),
as loading the correct values and calling the correct functions for a given CSP is handled by the [`cloudcmd` package](#cloudcmd).
### [`upgrade`](./internal/upgrade)
This package implements some logic to upgrade resources for new Constellation releases.
TODO: Remove this package, since it s functionality should be implemented by other packages.

View File

@ -5,16 +5,17 @@ SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package cloudcmd provides executable command for the CLI.
Package cloudcmd provides executable commands for the CLI.
This package focuses on the interaction with the cloud provider.
It separates the cloud provider specific code from the rest of the CLI, and
provides a common interface for all cloud providers.
Exported functions must not be cloud provider specific, but rather take a
cloudprovider.Provider as an argument.
cloudprovider.Provider as an argument, perform CSP specific logic, and return a universally usable result.
User interaction happens in the cmd package, and should not happen or pass through
It is used by the "cmd" to handle creation of cloud resources and other CSP specific interactions.
User interaction happens in the "cmd" package, and should not happen or pass through
this package.
The backend to this package is currently provided by the terraform package.

View File

@ -4,6 +4,8 @@ Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
// package clusterid defines the structure of the Constellation cluster ID file.
// Logic in this package should be kept minimal.
package clusterid
import (

View File

@ -8,5 +8,15 @@ SPDX-License-Identifier: AGPL-3.0-only
Package cmd provides the Constellation CLI.
It is responsible for the interaction with the user.
Logic should be kept to input/output parsing whenever possible.
Any more complex code should usually be implemented in one of the other CLI packages.
The code here should be kept as cloud provider agnostic as possible.
Any CSP specific tasks should be handled by the "cloudcmd" package.
All filepaths handled by the CLI code should originate from here.
Common filepaths are defined as constants in the global "/internal/constants" package.
To generate workspace correct filepaths for printing, use the functions from the "workspace" package.
*/
package cmd

View File

@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
*/
// package featureset provides a way to check whether a feature is enabled in the current build.
// This package should not implement any logic itself, but only define constants that are set at build time.
package featureset
// Edition is the edition of a build.

View File

@ -5,14 +5,26 @@ SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package helm provides a higher level interface to the Helm GO SDK.
Package helm provides a higher level interface to the Helm Go SDK.
It is used by the CLI to:
- load embedded charts
- install charts
- update helm releases
- get versions for installed helm releases
- create local backups before running service upgrades
- load embedded charts
- install charts
- update helm releases
- get versions for installed helm releases
- create local backups before running service upgrades
The charts themselves are embedded in the CLI binary, and values are dynamically updated depending on configuration.
The charts can be found in ./charts/.
Values should be added in the chart's "values.yaml file if they are static i.e. don't depend on user input,
otherwise they need to be dynamically created depending on a user's configuration.
Helm logic should not be implemented outside this package.
All values loading, parsing, installing, uninstalling, and updating of charts should be implemented here.
As such, the helm package requires to implement some CSP specific logic.
However, exported functions should be CSP agnostic and take a cloudprovider.Provider as argument.
As such, the number of exported functions should be kept minimal.
*/
package helm

View File

@ -5,9 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package kubernetes provides functions to interact with a live cluster to the CLI.
Package kubernetes provides functions to interact with a Kubernetes cluster to the CLI.
The package should be used for:
Currently it is used to implement the status and upgrade commands.
- Fetching status information about the cluster
- Creating, deleting, or migrating resources not managed by Helm
The package should not be used for anything that doesn't just require the Kubernetes API.
For example, Terraform and Helm actions should not be accessed by this package.
*/
package kubernetes

View File

@ -4,7 +4,11 @@ Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
// Package libvirt is used to start and stop containerized libvirt instances.
/*
Package libvirt is used to start and stop containerized libvirt instances.
The code in this package should be kept minimal, and likely won't need to be changed unless we do a major refactoring of our QEMU/libvirt installation.
*/
package libvirt
import (

View File

@ -5,12 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package terraform handles creation/destruction of a Constellation cluster using Terraform.
Package terraform handles creation/destruction of cloud and IAM resources required by Constellation using Terraform.
Since Terraform does not provide a stable Go API, we use the `terraform-exec` package to interact with Terraform.
The Terraform templates are located in the "terraform" subdirectory. The templates are embedded into the CLI binary using `go:embed`.
On use the relevant template is extracted to the working directory and the user customized variables are written to a `terraform.tfvars` file.
Functions in this package should be kept CSP agnostic (there should be no "CreateAzureCluster" function),
as loading the correct values and calling the correct functions for a given CSP is handled by the `cloudcmd` package.
*/
package terraform

View File

@ -5,6 +5,10 @@ SPDX-License-Identifier: AGPL-3.0-only
*/
/*
Package upgrade provides functionality to upgrade the cluster and it's resources
Package upgrade provides functionality to upgrade the cluster and it's resources.
TODO: Remove this package in favour of adding splitting its functionality onto the kubernetes, helm, and terraform packages.
There should be no additions to this package at the current time.
If you need to make larger changes to existing code, consider refactoring and moving relevant code to the kubernetes, helm, or terraform packages.
*/
package upgrade