github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/server_info.go (about) 1 /* 2 Copyright 2023 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/utils" 27 ) 28 29 // ServerInfo represents info that should be applied to joining Nodes. 30 type ServerInfo interface { 31 // ResourceWithLabels provides common resource headers 32 ResourceWithLabels 33 // GetNewLabels gets the labels to apply to matched Nodes. 34 GetNewLabels() map[string]string 35 // SetNewLabels sets the labels to apply to matched Nodes. 36 SetNewLabels(map[string]string) 37 } 38 39 // NewServerInfo creates an instance of ServerInfo. 40 func NewServerInfo(meta Metadata, spec ServerInfoSpecV1) (ServerInfo, error) { 41 si := &ServerInfoV1{ 42 Metadata: meta, 43 Spec: spec, 44 } 45 if err := si.CheckAndSetDefaults(); err != nil { 46 return nil, trace.Wrap(err) 47 } 48 return si, nil 49 } 50 51 // GetKind returns resource kind 52 func (s *ServerInfoV1) GetKind() string { 53 return s.Kind 54 } 55 56 // GetSubKind returns resource subkind 57 func (s *ServerInfoV1) GetSubKind() string { 58 return s.SubKind 59 } 60 61 // SetSubKind sets resource subkind 62 func (s *ServerInfoV1) SetSubKind(subkind string) { 63 s.SubKind = subkind 64 } 65 66 // GetVersion returns resource version 67 func (s *ServerInfoV1) GetVersion() string { 68 return s.Version 69 } 70 71 // GetName returns the name of the resource 72 func (s *ServerInfoV1) GetName() string { 73 return s.Metadata.Name 74 } 75 76 // SetName sets the name of the resource 77 func (s *ServerInfoV1) SetName(name string) { 78 s.Metadata.Name = name 79 } 80 81 // Expiry returns object expiry setting 82 func (s *ServerInfoV1) Expiry() time.Time { 83 return s.Metadata.Expiry() 84 } 85 86 // SetExpiry sets object expiry 87 func (s *ServerInfoV1) SetExpiry(expiry time.Time) { 88 s.Metadata.SetExpiry(expiry) 89 } 90 91 // GetMetadata returns object metadata 92 func (s *ServerInfoV1) GetMetadata() Metadata { 93 return s.Metadata 94 } 95 96 // GetResourceID returns resource ID 97 func (s *ServerInfoV1) GetResourceID() int64 { 98 return s.Metadata.ID 99 } 100 101 // SetResourceID sets resource ID 102 func (s *ServerInfoV1) SetResourceID(id int64) { 103 s.Metadata.ID = id 104 } 105 106 // GetRevision returns the revision 107 func (s *ServerInfoV1) GetRevision() string { 108 return s.Metadata.GetRevision() 109 } 110 111 // SetRevision sets the revision 112 func (s *ServerInfoV1) SetRevision(rev string) { 113 s.Metadata.SetRevision(rev) 114 } 115 116 // Origin returns the origin value of the resource. 117 func (s *ServerInfoV1) Origin() string { 118 return s.Metadata.Origin() 119 } 120 121 // SetOrigin sets the origin value of the resource. 122 func (s *ServerInfoV1) SetOrigin(o string) { 123 s.Metadata.SetOrigin(o) 124 } 125 126 // GetLabel retrieves the label with the provided key. 127 func (s *ServerInfoV1) GetLabel(key string) (string, bool) { 128 value, ok := s.Metadata.Labels[key] 129 return value, ok 130 } 131 132 // GetAllLabels returns all resource's labels. 133 func (s *ServerInfoV1) GetAllLabels() map[string]string { 134 return s.Metadata.Labels 135 } 136 137 // GetStaticLabels returns the resource's static labels. 138 func (s *ServerInfoV1) GetStaticLabels() map[string]string { 139 return s.Metadata.Labels 140 } 141 142 // SetStaticLabels sets the resource's static labels. 143 func (s *ServerInfoV1) SetStaticLabels(sl map[string]string) { 144 s.Metadata.Labels = sl 145 } 146 147 // MatchSearch goes through select field values of a resource 148 // and tries to match against the list of search values. 149 func (s *ServerInfoV1) MatchSearch(searchValues []string) bool { 150 fieldVals := append( 151 utils.MapToStrings(s.GetAllLabels()), 152 s.GetName(), 153 ) 154 return MatchSearch(fieldVals, searchValues, nil) 155 } 156 157 // GetNewLabels gets the labels to apply to matched Nodes. 158 func (s *ServerInfoV1) GetNewLabels() map[string]string { 159 return s.Spec.NewLabels 160 } 161 162 // SetNewLabels sets the labels to apply to matched Nodes. 163 func (s *ServerInfoV1) SetNewLabels(labels map[string]string) { 164 s.Spec.NewLabels = labels 165 s.fixLabels() 166 } 167 168 // fixLabels sets the namespace of this ServerInfo's labels to match the 169 // matching scheme indicated by the name. 170 func (s *ServerInfoV1) fixLabels() { 171 // Determine which prefix the labels need, if any. 172 namePrefix, _, found := strings.Cut(s.GetName(), "-") 173 if !found { 174 return 175 } 176 var labelPrefix string 177 switch namePrefix { 178 case "aws": 179 labelPrefix = "aws/" 180 case "si": 181 labelPrefix = TeleportDynamicLabelPrefix 182 default: 183 return 184 } 185 186 // Replace the prefix on existing labels. 187 for k, v := range s.Spec.NewLabels { 188 prefix, name, _ := strings.Cut(k, "/") 189 if name == "" { 190 name = prefix 191 } 192 delete(s.Spec.NewLabels, k) 193 s.Spec.NewLabels[labelPrefix+name] = v 194 } 195 } 196 197 func (s *ServerInfoV1) setStaticFields() { 198 s.Kind = KindServerInfo 199 s.Version = V1 200 s.SubKind = SubKindCloudInfo 201 } 202 203 // CheckAndSetDefaults validates the Resource and sets any empty fields to 204 // default values. 205 func (s *ServerInfoV1) CheckAndSetDefaults() error { 206 s.setStaticFields() 207 s.fixLabels() 208 return trace.Wrap(s.Metadata.CheckAndSetDefaults()) 209 } 210 211 // ServerInfoNameFromAWS gets the name of the ServerInfo that matches the node 212 // with the given AWS account ID and instance ID. 213 func ServerInfoNameFromAWS(accountID, instanceID string) string { 214 return fmt.Sprintf("aws-%v-%v", accountID, instanceID) 215 } 216 217 // ServerInfoNameFromNodeName gets the name of the ServerInfo that matches the 218 // node with the given name. 219 func ServerInfoNameFromNodeName(name string) string { 220 return fmt.Sprintf("si-%v", name) 221 } 222 223 // ServerInfoForServer returns a ServerInfo from a Server 224 func ServerInfoForServer(server Server) (ServerInfo, error) { 225 return NewServerInfo( 226 Metadata{ 227 Name: serverInfoNameFromServer(server), 228 }, 229 ServerInfoSpecV1{}, 230 ) 231 } 232 233 // serverInfoNameFromServer returns the ServerInfo name for this Server. 234 func serverInfoNameFromServer(s Server) string { 235 awsAccountID := s.GetAWSAccountID() 236 awsInstanceID := s.GetAWSInstanceID() 237 238 if awsAccountID != "" && awsInstanceID != "" { 239 return ServerInfoNameFromAWS(awsAccountID, awsInstanceID) 240 } 241 242 return ServerInfoNameFromNodeName(s.GetName()) 243 }