Path: blob/main/components/common-go/kubernetes/kubernetes.go
2498 views
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package kubernetes56// Those two are the only cases where you would actually need this package. If you think you need this elsewhere,7// please make sure you're not better of using wsman's API to solve your problem. If this is actually what you need,8// please update this comment.9//1011import (12"context"13"math"1415"github.com/sirupsen/logrus"16corev1 "k8s.io/api/core/v1"17metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"1819"github.com/gitpod-io/gitpod/common-go/log"20)2122const (23// WorkspaceIDLabel is the label which contains the workspaceID. We duplicate this information with the annotations to make selection easier24WorkspaceIDLabel = "workspaceID"2526// OwnerLabel is the label of the workspace's owner27OwnerLabel = "owner"2829// MetaIDLabel is the label of the workspace meta ID (just workspace ID outside of wsman)30MetaIDLabel = "metaID"3132// ProjectLabel is the label for the workspace's project33ProjectLabel = "project"3435// TeamLabel is the label for the workspace's team36TeamLabel = "team"3738// TypeLabel marks the workspace type39TypeLabel = "workspaceType"4041// ServiceTypeLabel help differentiate between port service and IDE service42ServiceTypeLabel = "serviceType"4344// WorkspaceManaged indicates which component is responsible for managing the workspace45WorkspaceManagedByLabel = "gitpod.io/managed-by"4647// CPULimitAnnotation enforces a strict CPU limit on a workspace by virtue of ws-daemon48CPULimitAnnotation = "gitpod.io/cpuLimit"4950// WorkspaceURLAnnotation is the annotation on the WS pod which contains the public workspace URL.51WorkspaceURLAnnotation = "gitpod/url"5253// OwnerTokenAnnotation contains the owner token of the workspace.54OwnerTokenAnnotation = "gitpod/ownerToken"5556// WorkspaceAdmissionAnnotation determines the user admission to a workspace, i.e. if it can be accessed by everyone without token.57WorkspaceAdmissionAnnotation = "gitpod/admission"5859// WorkspaceImageSpecAnnotation contains the protobuf serialized image spec in base64 encoding. We need to keep this around post-request60// to provide this information to the registry facade later in the workspace's lifecycle.61WorkspaceImageSpecAnnotation = "gitpod/imageSpec"6263// WorkspaceExposedPorts contains the exposed ports in the workspace64WorkspaceExposedPorts = "gitpod/exposedPorts"6566// WorkspaceSSHPublicKeys contains all authorized ssh public keys that can be connected to the workspace67WorkspaceSSHPublicKeys = "gitpod.io/sshPublicKeys"6869// workspaceCpuMinLimitAnnotation denotes the minimum cpu limit of a workspace i.e. the minimum amount of resources it is guaranteed to get70WorkspaceCpuMinLimitAnnotation = "gitpod.io/cpuMinLimit"7172// workspaceCpuBurstLimit denotes the cpu burst limit of a workspace73WorkspaceCpuBurstLimitAnnotation = "gitpod.io/cpuBurstLimit"7475// workspaceNetConnLimit denotes the maximum number of connections a workspace can make per minute76WorkspaceNetConnLimitAnnotation = "gitpod.io/netConnLimitPerMinute"7778// workspacePressureStallInfo indicates if pressure stall information should be retrieved for the workspace79WorkspacePressureStallInfoAnnotation = "gitpod.io/psi"8081// ImageNameAnnotation indicates the original format of the main image of the pod82ImageNameAnnotation = "gitpod.io/image_name"83)8485// GetOWIFromObject finds the owner, workspace and instance information on a Kubernetes object using labels86func GetOWIFromObject(pod *metav1.ObjectMeta) logrus.Fields {87owner := pod.Labels[OwnerLabel]88workspace := pod.Labels[MetaIDLabel]89instance := pod.Labels[WorkspaceIDLabel]90project := pod.Labels[ProjectLabel]91team := pod.Labels[TeamLabel]92return log.LogContext(owner, workspace, instance, project, team)93}9495// UnlimitedRateLimiter implements an empty, unlimited flowcontrol.RateLimiter96type UnlimitedRateLimiter struct {97}9899// TryAccept returns true if a token is taken immediately. Otherwise,100// it returns false.101func (u *UnlimitedRateLimiter) TryAccept() bool {102return true103}104105// Accept returns once a token becomes available.106func (u *UnlimitedRateLimiter) Accept() {107}108109// Stop stops the rate limiter, subsequent calls to CanAccept will return false110func (u *UnlimitedRateLimiter) Stop() {111}112113// QPS returns QPS of this rate limiter114func (u *UnlimitedRateLimiter) QPS() float32 {115return math.MaxFloat32116}117118// Wait returns nil if a token is taken before the Context is done.119func (u *UnlimitedRateLimiter) Wait(ctx context.Context) error {120return nil121}122123func IsWorkspace(pod *corev1.Pod) bool {124val, ok := pod.ObjectMeta.Labels["component"]125return ok && val == "workspace"126}127128func IsHeadlessWorkspace(pod *corev1.Pod) bool {129if !IsWorkspace(pod) {130return false131}132133val, ok := pod.ObjectMeta.Labels["headless"]134return ok && val == "true"135}136137func IsRegularWorkspace(pod *corev1.Pod) bool {138if !IsWorkspace(pod) {139return false140}141142val, ok := pod.ObjectMeta.Labels[TypeLabel]143return ok && val == "regular"144}145146func GetWorkspaceType(pod *corev1.Pod) string {147val, ok := pod.ObjectMeta.Labels[TypeLabel]148if !ok {149return ""150}151return val152}153154// AddUniqueCondition adds a condition if it doesn't exist already155func AddUniqueCondition(conds []metav1.Condition, cond metav1.Condition) []metav1.Condition {156if cond.Reason == "" {157cond.Reason = "Unknown"158}159160for i, c := range conds {161if c.Type == cond.Type {162conds[i] = cond163return conds164}165}166167return append(conds, cond)168}169170// GetCondition returns a condition from a list. If not present, it returns nil.171func GetCondition(conds []metav1.Condition, tpe string) *metav1.Condition {172for _, c := range conds {173if c.Type == tpe {174return &c175}176}177return nil178}179180// ConditionPresentAndTrue returns whether a condition is present and its status set to True.181func ConditionPresentAndTrue(cond []metav1.Condition, tpe string) bool {182for _, c := range cond {183if c.Type == tpe {184return c.Status == metav1.ConditionTrue185}186}187return false188}189190// ConditionWithStatusAndReason returns whether a condition is present, and with the given Reason.191func ConditionWithStatusAndReason(cond []metav1.Condition, tpe string, status bool, reason string) bool {192st := metav1.ConditionFalse193if status {194st = metav1.ConditionTrue195}196for _, c := range cond {197if c.Type == tpe {198return c.Type == tpe && c.Status == st && c.Reason == reason199}200}201return false202}203204205