uselagoon / lagoon

Lagoon, the developer-focused application delivery platform
https://docs.lagoon.sh/
Apache License 2.0
555 stars 148 forks source link

Proposal: standardise on styling for kubernetes labels used by Lagoon #3597

Open shreddedbacon opened 9 months ago

shreddedbacon commented 9 months ago

Proposal

A standard for the labels Lagoon uses in kubernetes.

Current Style

Currently we use the following style for labels. A mixture of camelCase, kebab-case, and probably other styles that are to be discovered, depending on when the label was initially defined. More often we utilise camelCase. This can be problematic as it results in weird long labels that can be confusing to look at, and if an external system has influenced them, in some cases, changes them to all lowercase for fun.

lagoon.sh/project
lagoon.sh/projectId
lagoon.sh/environment
lagoon.sh/environmentId
lagoon.sh/environmentType
lagoon.sh/branch
lagoon.sh/service-type
lagoon.sh/service
lagoon.sh/storageCalculatorEnabled
lagoon.sh/environmentIdlingEnabled**
lagoon.sh/projectIdlingEnabled**
lagoon.sh/buildName
lagoon.sh/buildRemoteID
lagoon.sh/buildStep
lagoon.sh/jobType
etc..

New Style

My proposal is to use lowercase domain name structures and kebab-case where possible, this makes it clearer at what its purpose is, and its relationship back to lagoon. It also follows more common labelling styles that you see in kubernetes generally (and follow the kubernetes syntax rules)

project.lagoon.sh/name
project.lagoon.sh/id
environment.lagoon.sh/name
environment.lagoon.sh/id
environment.lagoon.sh/type
environment.lagoon.sh/branch
service.lagoon.sh/type
service.lagoon.sh/name
storagecalculator.lagoon.sh/enabled
idling.environment.lagoon.sh/enabled**
idling.project.lagoon.sh/enabled**
build.lagoon.sh/name
build.lagoon.sh/remote-id
build.lagoon.sh/step
job.lagoon.sh/type
etc.

Label Structure / Style Pattern

The structure of the labels as part of this proposal is as follows

[resource/component].lagoon.sh/value

The reasons for choosing this structure is to be able to, at a glance, see what type of resource the label is sourced from or used by. Being able to quickly determine which resource or component is being referenced by only reading the domain part, then scanning the path for the value.

Breaking down the structure, the resource/component section of the domain would be the reference resource or component that the value is from, or the value is used by. In most cases, this would be project, environment, route, service. But there are other things that this could be referencing, this being whatever is most appropriate to what the value would be used for. In the example list above, you can see there is reference to storagecalculator. The storage calculator component would use this label to know if it should scan whichever resource has the label (in this case, the namespace).

The value would be the type of data you are storing, this could be a name, or an ID. It could be used to enable or disable functionality, or identify if some functionality is enabled. Or it could be generic data if in an annotation. But the value should describe what is contained within said label or annotation as clearly as possible.

Looking at the initial suggested labels, you can see that all the resources/components are the leading section, so at a glance you know you're looking at a project or and environment sourced value, and then the path after the domain is the value to reference.

By seeing project.lagoon.sh/name you can know for certain that this value references the project name. The same for knowing if you need the project ID, you can know it will be available under project.lagoon.sh/id. If you need to know if a route is the primary, there will be a route.lagoon.sh/primary label that would be true or false.

Part of the discovery/documentation phase of the work to standardise on label structure/styles would be to document all the standard labels, where they are used, which systems may consume them, etc... The introduction of any new labels should go through the standards to ensure they meet the requirements as closely as possible, understandably not all cases will fit, but if the label is clearly documented and made known, then it may be acceptable.

Some inspiration for the structure is from kubernetes itself, where there is a list of well-known labels, annotations, and taints. You can see some similarities that kubernetes applies in the structure proposed here. Where they use kubernetes.io as the domain root, but use a resource or component when referencing resources such as app, applyset, config, service, and then other systems like cluster-autoscaler, or node.


Considerations


** we currently provide two labels for idling, but these seem useless when the main bit of information to know is if the environment has idling enabled or not, not whether the idling being enabled was determined from the project or the environment. The remote-controller sets these labels, and it can handle the checks required to determine if the environment has idling enabled or not from the two provided values and set just the single label directly.

tobybellwood commented 4 months ago

At a similar time, we can potentially look to implement https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/

roughly it could go: Kubernetes Label Lagoon Equivalent
app.kubernetes.io/managed-by build deploy tool
app.kubernetes.io/version service template version
app.kubernetes.io/part-of namespace
app.kubernetes.io/component Lagoon Service Type
app.kubernetes.io/name Lagoon Service Name

This should allow any tools that recognise applications to see each "site" as a standalone application, with components.