github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/matchers_aws.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 "slices" 21 22 "github.com/gravitational/trace" 23 24 apiutils "github.com/gravitational/teleport/api/utils" 25 awsapiutils "github.com/gravitational/teleport/api/utils/aws" 26 ) 27 28 const ( 29 // IAMInviteTokenName is the name of the default Teleport IAM 30 // token to use when templating the script to be executed. 31 IAMInviteTokenName = "aws-discovery-iam-token" 32 33 // SSHDConfigPath is the path to the sshd config file to modify 34 // when using the agentless installer 35 SSHDConfigPath = "/etc/ssh/sshd_config" 36 37 // AWSInstallerDocument is the name of the default AWS document 38 // that will be called when executing the SSM command. 39 AWSInstallerDocument = "TeleportDiscoveryInstaller" 40 41 // AWSAgentlessInstallerDocument is the name of the default AWS document 42 // that will be called when executing the SSM command . 43 AWSAgentlessInstallerDocument = "TeleportAgentlessDiscoveryInstaller" 44 45 // AWSMatcherEC2 is the AWS matcher type for EC2 instances. 46 AWSMatcherEC2 = "ec2" 47 // AWSMatcherEKS is the AWS matcher type for AWS Kubernetes. 48 AWSMatcherEKS = "eks" 49 // AWSMatcherRDS is the AWS matcher type for RDS databases. 50 AWSMatcherRDS = "rds" 51 // AWSMatcherRDSProxy is the AWS matcher type for RDS Proxy databases. 52 AWSMatcherRDSProxy = "rdsproxy" 53 // AWSMatcherRedshift is the AWS matcher type for Redshift databases. 54 AWSMatcherRedshift = "redshift" 55 // AWSMatcherRedshiftServerless is the AWS matcher type for Redshift Serverless databases. 56 AWSMatcherRedshiftServerless = "redshift-serverless" 57 // AWSMatcherElastiCache is the AWS matcher type for ElastiCache databases. 58 AWSMatcherElastiCache = "elasticache" 59 // AWSMatcherMemoryDB is the AWS matcher type for MemoryDB databases. 60 AWSMatcherMemoryDB = "memorydb" 61 // AWSMatcherOpenSearch is the AWS matcher type for OpenSearch databases. 62 AWSMatcherOpenSearch = "opensearch" 63 ) 64 65 // SupportedAWSMatchers is list of AWS services currently supported by the 66 // Teleport discovery service. 67 var SupportedAWSMatchers = append([]string{ 68 AWSMatcherEC2, 69 AWSMatcherEKS, 70 }, SupportedAWSDatabaseMatchers...) 71 72 // SupportedAWSDatabaseMatchers is a list of the AWS databases currently 73 // supported by the Teleport discovery service. 74 // IMPORTANT: when adding new Database matchers, make sure reference configs 75 // for both Discovery and Database Service are updated in docs. 76 var SupportedAWSDatabaseMatchers = []string{ 77 AWSMatcherRDS, 78 AWSMatcherRDSProxy, 79 AWSMatcherRedshift, 80 AWSMatcherRedshiftServerless, 81 AWSMatcherElastiCache, 82 AWSMatcherMemoryDB, 83 AWSMatcherOpenSearch, 84 } 85 86 // RequireAWSIAMRolesAsUsersMatchers is a list of the AWS databases that 87 // require AWS IAM roles as database users. 88 // IMPORTANT: if you add database matchers for AWS keyspaces, OpenSearch, or 89 // DynamoDB discovery, add them here and in RequireAWSIAMRolesAsUsers in 90 // api/types. 91 var RequireAWSIAMRolesAsUsersMatchers = []string{ 92 AWSMatcherRedshiftServerless, 93 AWSMatcherOpenSearch, 94 } 95 96 // GetTypes gets the types that the matcher can match. 97 func (m AWSMatcher) GetTypes() []string { 98 return m.Types 99 } 100 101 // CopyWithTypes copies the matcher with new types. 102 func (m AWSMatcher) CopyWithTypes(t []string) Matcher { 103 newMatcher := m 104 newMatcher.Types = t 105 return newMatcher 106 } 107 108 // CheckAndSetDefaults that the matcher is correct and adds default values. 109 func (m *AWSMatcher) CheckAndSetDefaults() error { 110 for _, matcherType := range m.Types { 111 if !slices.Contains(SupportedAWSMatchers, matcherType) { 112 return trace.BadParameter("discovery service type does not support %q, supported resource types are: %v", 113 matcherType, SupportedAWSMatchers) 114 } 115 } 116 117 if len(m.Types) == 0 { 118 return trace.BadParameter("discovery service requires at least one type") 119 } 120 121 if len(m.Regions) == 0 { 122 return trace.BadParameter("discovery service requires at least one region") 123 } 124 125 for _, region := range m.Regions { 126 if err := awsapiutils.IsValidRegion(region); err != nil { 127 return trace.BadParameter("discovery service does not support region %q", region) 128 } 129 } 130 131 if m.AssumeRole != nil { 132 if m.AssumeRole.RoleARN != "" { 133 if err := awsapiutils.CheckRoleARN(m.AssumeRole.RoleARN); err != nil { 134 return trace.BadParameter("invalid assume role: %v", err) 135 } 136 } else if m.AssumeRole.ExternalID != "" { 137 for _, t := range m.Types { 138 if !slices.Contains(RequireAWSIAMRolesAsUsersMatchers, t) { 139 return trace.BadParameter("discovery service AWS matcher assume_role_arn is empty, but has external_id %q", 140 m.AssumeRole.ExternalID) 141 } 142 } 143 } 144 } 145 146 if m.Tags == nil || len(m.Tags) == 0 { 147 m.Tags = map[string]apiutils.Strings{Wildcard: {Wildcard}} 148 } 149 150 if m.Params == nil { 151 m.Params = &InstallerParams{ 152 InstallTeleport: true, 153 } 154 } 155 156 switch m.Params.JoinMethod { 157 case JoinMethodIAM, "": 158 m.Params.JoinMethod = JoinMethodIAM 159 default: 160 return trace.BadParameter("only IAM joining is supported for EC2 auto-discovery") 161 } 162 163 if m.Params.JoinToken == "" { 164 m.Params.JoinToken = IAMInviteTokenName 165 } 166 167 if m.Params.SSHDConfig == "" { 168 m.Params.SSHDConfig = SSHDConfigPath 169 } 170 171 if m.Params.ScriptName == "" { 172 m.Params.ScriptName = DefaultInstallerScriptNameAgentless 173 if m.Params.InstallTeleport { 174 m.Params.ScriptName = DefaultInstallerScriptName 175 } 176 } 177 178 if m.SSM == nil { 179 m.SSM = &AWSSSM{} 180 } 181 182 if m.SSM.DocumentName == "" { 183 m.SSM.DocumentName = AWSAgentlessInstallerDocument 184 if m.Params.InstallTeleport { 185 m.SSM.DocumentName = AWSInstallerDocument 186 } 187 } 188 return nil 189 }