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 }