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

     1  /*
     2  Copyright 2020 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 types
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  	"time"
    23  
    24  	"github.com/gravitational/trace"
    25  
    26  	"github.com/gravitational/teleport/api/defaults"
    27  )
    28  
    29  // TunnelConnection is SSH reverse tunnel connection
    30  // established to reverse tunnel proxy
    31  type TunnelConnection interface {
    32  	// Resource provides common methods for resource objects
    33  	Resource
    34  	// GetClusterName returns name of the cluster this connection is for.
    35  	GetClusterName() string
    36  	// GetProxyName returns the proxy name this connection is established to
    37  	GetProxyName() string
    38  	// GetLastHeartbeat returns time of the last heartbeat received from
    39  	// the tunnel over the connection
    40  	GetLastHeartbeat() time.Time
    41  	// SetLastHeartbeat sets last heartbeat time
    42  	SetLastHeartbeat(time.Time)
    43  	// GetType gets the type of ReverseTunnel.
    44  	GetType() TunnelType
    45  	// SetType sets the type of ReverseTunnel.
    46  	SetType(TunnelType)
    47  	// String returns user friendly representation of this connection
    48  	String() string
    49  	// Clone returns a copy of this tunnel connection
    50  	Clone() TunnelConnection
    51  }
    52  
    53  // NewTunnelConnection returns new connection from V2 spec
    54  func NewTunnelConnection(name string, spec TunnelConnectionSpecV2) (TunnelConnection, error) {
    55  	conn := &TunnelConnectionV2{
    56  		SubKind: spec.ClusterName,
    57  		Metadata: Metadata{
    58  			Name: name,
    59  		},
    60  		Spec: spec,
    61  	}
    62  	if err := conn.CheckAndSetDefaults(); err != nil {
    63  		return nil, trace.Wrap(err)
    64  	}
    65  	return conn, nil
    66  }
    67  
    68  // GetVersion returns resource version
    69  func (r *TunnelConnectionV2) GetVersion() string {
    70  	return r.Version
    71  }
    72  
    73  // GetKind returns resource kind
    74  func (r *TunnelConnectionV2) GetKind() string {
    75  	return r.Kind
    76  }
    77  
    78  // GetSubKind returns resource sub kind
    79  func (r *TunnelConnectionV2) GetSubKind() string {
    80  	return r.SubKind
    81  }
    82  
    83  // SetSubKind sets resource subkind
    84  func (r *TunnelConnectionV2) SetSubKind(s string) {
    85  	r.SubKind = s
    86  }
    87  
    88  // GetResourceID returns resource ID
    89  func (r *TunnelConnectionV2) GetResourceID() int64 {
    90  	return r.Metadata.ID
    91  }
    92  
    93  // SetResourceID sets resource ID
    94  func (r *TunnelConnectionV2) SetResourceID(id int64) {
    95  	r.Metadata.ID = id
    96  }
    97  
    98  // GetRevision returns the revision
    99  func (r *TunnelConnectionV2) GetRevision() string {
   100  	return r.Metadata.GetRevision()
   101  }
   102  
   103  // SetRevision sets the revision
   104  func (r *TunnelConnectionV2) SetRevision(rev string) {
   105  	r.Metadata.SetRevision(rev)
   106  }
   107  
   108  // Clone returns a copy of this tunnel connection
   109  func (r *TunnelConnectionV2) Clone() TunnelConnection {
   110  	out := *r
   111  	return &out
   112  }
   113  
   114  // String returns user-friendly description of this connection
   115  func (r *TunnelConnectionV2) String() string {
   116  	return fmt.Sprintf("TunnelConnection(name=%v, type=%v, cluster=%v, proxy=%v)",
   117  		r.Metadata.Name, r.Spec.Type, r.Spec.ClusterName, r.Spec.ProxyName)
   118  }
   119  
   120  // GetMetadata returns object metadata
   121  func (r *TunnelConnectionV2) GetMetadata() Metadata {
   122  	return r.Metadata
   123  }
   124  
   125  // SetExpiry sets expiry time for the object
   126  func (r *TunnelConnectionV2) SetExpiry(expires time.Time) {
   127  	r.Metadata.SetExpiry(expires)
   128  }
   129  
   130  // Expiry returns object expiry setting
   131  func (r *TunnelConnectionV2) Expiry() time.Time {
   132  	return r.Metadata.Expiry()
   133  }
   134  
   135  // GetName returns the name of the User
   136  func (r *TunnelConnectionV2) GetName() string {
   137  	return r.Metadata.Name
   138  }
   139  
   140  // SetName sets the name of the User
   141  func (r *TunnelConnectionV2) SetName(e string) {
   142  	r.Metadata.Name = e
   143  }
   144  
   145  // V2 returns V2 version of the resource
   146  func (r *TunnelConnectionV2) V2() *TunnelConnectionV2 {
   147  	return r
   148  }
   149  
   150  // setStaticFields sets static resource header and metadata fields.
   151  func (r *TunnelConnectionV2) setStaticFields() {
   152  	r.Kind = KindTunnelConnection
   153  	r.Version = V2
   154  }
   155  
   156  // CheckAndSetDefaults checks and sets default values
   157  func (r *TunnelConnectionV2) CheckAndSetDefaults() error {
   158  	r.setStaticFields()
   159  	if err := r.Metadata.CheckAndSetDefaults(); err != nil {
   160  		return trace.Wrap(err)
   161  	}
   162  
   163  	if r.Expiry().IsZero() {
   164  		// calculate an appropriate expiry if one was not provided.
   165  		// tunnel connection resources are ephemeral and trigger
   166  		// allocations in proxies, so it is important that they expire
   167  		// in a timely manner.
   168  		from := r.GetLastHeartbeat()
   169  		if from.IsZero() {
   170  			from = time.Now()
   171  		}
   172  		r.SetExpiry(from.UTC().Add(defaults.ServerAnnounceTTL))
   173  	}
   174  
   175  	if strings.TrimSpace(r.Spec.ClusterName) == "" {
   176  		return trace.BadParameter("empty cluster name")
   177  	}
   178  	if len(r.Spec.ProxyName) == 0 {
   179  		return trace.BadParameter("missing parameter proxy name")
   180  	}
   181  
   182  	return nil
   183  }
   184  
   185  // GetClusterName returns name of the cluster
   186  func (r *TunnelConnectionV2) GetClusterName() string {
   187  	return r.Spec.ClusterName
   188  }
   189  
   190  // GetProxyName returns the name of the proxy
   191  func (r *TunnelConnectionV2) GetProxyName() string {
   192  	return r.Spec.ProxyName
   193  }
   194  
   195  // GetLastHeartbeat returns last heartbeat
   196  func (r *TunnelConnectionV2) GetLastHeartbeat() time.Time {
   197  	return r.Spec.LastHeartbeat
   198  }
   199  
   200  // SetLastHeartbeat sets last heartbeat time
   201  func (r *TunnelConnectionV2) SetLastHeartbeat(tm time.Time) {
   202  	r.Spec.LastHeartbeat = tm
   203  }
   204  
   205  // GetType gets the type of ReverseTunnel.
   206  func (r *TunnelConnectionV2) GetType() TunnelType {
   207  	if string(r.Spec.Type) == "" {
   208  		return ProxyTunnel
   209  	}
   210  	return r.Spec.Type
   211  }
   212  
   213  // SetType sets the type of ReverseTunnel.
   214  func (r *TunnelConnectionV2) SetType(tt TunnelType) {
   215  	r.Spec.Type = tt
   216  }