github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/kubewaitingcontainer/kubewaitingcontainer.go (about)

     1  /*
     2  Copyright 2024 Gravitational, Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package kubewaitingcontainer
    18  
    19  import (
    20  	"slices"
    21  	"time"
    22  
    23  	"github.com/gravitational/trace"
    24  	"google.golang.org/protobuf/types/known/timestamppb"
    25  
    26  	headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
    27  	kubewaitingcontainerpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/kubewaitingcontainer/v1"
    28  	"github.com/gravitational/teleport/api/types"
    29  )
    30  
    31  const (
    32  	// JSONPatchType is the JSON patch type supported by Kubernetes
    33  	JSONPatchType string = "application/json-patch+json"
    34  	// MergePatchType is the merge patch type supported by Kubernetes
    35  	MergePatchType string = "application/merge-patch+json"
    36  	// StrategicMergePatchType is the strategic merge patch type supported by Kubernetes
    37  	StrategicMergePatchType string = "application/strategic-merge-patch+json"
    38  	// ApplyPatchType is the apply patch type supported by Kubernetes
    39  	ApplyPatchType string = "application/apply-patch+yaml"
    40  )
    41  
    42  var (
    43  	// PatchTypes is a list of all supported patch types
    44  	PatchTypes = []string{
    45  		JSONPatchType,
    46  		MergePatchType,
    47  		StrategicMergePatchType,
    48  		ApplyPatchType,
    49  	}
    50  )
    51  
    52  // NewKubeWaitingContainer creates a new Kubernetes ephemeral
    53  // container that are waiting to be created until moderated
    54  // session conditions are met.
    55  func NewKubeWaitingContainer(name string, spec *kubewaitingcontainerpb.KubernetesWaitingContainerSpec) (*kubewaitingcontainerpb.KubernetesWaitingContainer, error) {
    56  	waitingCont := &kubewaitingcontainerpb.KubernetesWaitingContainer{
    57  		Kind:    types.KindKubeWaitingContainer,
    58  		Version: types.V1,
    59  		Metadata: &headerv1.Metadata{
    60  			Name:    name,
    61  			Expires: timestamppb.New(time.Now().Add(time.Hour)),
    62  		},
    63  		Spec: spec,
    64  	}
    65  	if err := ValidateKubeWaitingContainer(waitingCont); err != nil {
    66  		return nil, trace.Wrap(err)
    67  	}
    68  
    69  	return waitingCont, nil
    70  }
    71  
    72  // ValidateKubeWaitingContainer checks that required parameters are set
    73  // for the specified KubeWaitingContainer
    74  func ValidateKubeWaitingContainer(k *kubewaitingcontainerpb.KubernetesWaitingContainer) error {
    75  	if k == nil {
    76  		return trace.BadParameter("KubernetesWaitingContainer is nil")
    77  	}
    78  	if k.Metadata == nil {
    79  		return trace.BadParameter("Metadata is nil")
    80  	}
    81  	if k.Spec == nil {
    82  		return trace.BadParameter("Spec is nil")
    83  	}
    84  
    85  	if k.Spec.Username == "" {
    86  		return trace.BadParameter("Username is unset")
    87  	}
    88  	if k.Spec.Cluster == "" {
    89  		return trace.BadParameter("KubeCluster is unset")
    90  	}
    91  	if k.Spec.Namespace == "" {
    92  		return trace.BadParameter("KubeNamespace is unset")
    93  	}
    94  	if k.Spec.PodName == "" {
    95  		return trace.BadParameter("PodName is unset")
    96  	}
    97  	if k.Spec.ContainerName == "" {
    98  		return trace.BadParameter("ContainerName is unset")
    99  	}
   100  	if len(k.Spec.Patch) == 0 {
   101  		return trace.BadParameter("Patch is unset")
   102  	}
   103  	if len(k.Spec.PatchType) == 0 {
   104  		return trace.BadParameter("PatchType is unset")
   105  	}
   106  	if !slices.Contains(PatchTypes, k.Spec.PatchType) {
   107  		return trace.BadParameter("PatchType is invalid: valid types are %v", PatchTypes)
   108  	}
   109  	if k.Metadata.Name == "" {
   110  		return trace.BadParameter("Name is unset")
   111  	}
   112  	if k.Metadata.Name != k.Spec.ContainerName {
   113  		return trace.BadParameter("Name must be ContainerName")
   114  	}
   115  
   116  	return nil
   117  }