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  }