DiscoveryMatchers: move checkandset to types package (#32857)

* DiscoveryMatchers: move checkandset to types package

* add opensearch to iamrole as users
This commit is contained in:
Marco André Dinis 2023-10-04 14:48:09 +01:00 committed by GitHub
parent 41edd25cb5
commit 44209ce8dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 1924 additions and 1278 deletions

View file

@ -1116,3 +1116,13 @@ const (
// JWTClaimsRewriteNone include neither traits nor roles in the JWT token.
JWTClaimsRewriteNone = "none"
)
const (
// DefaultInstallerScriptName is the name of the by default populated, EC2
// installer script
DefaultInstallerScriptName = "default-installer"
// DefaultInstallerScriptNameAgentless is the name of the by default populated, EC2
// installer script when agentless mode is enabled for a matcher
DefaultInstallerScriptNameAgentless = "default-agentless-installer"
)

View file

@ -30,11 +30,11 @@ var defaultAgentlessInstallScript string
// InstallerScriptName is the name of the by default populated, EC2
// installer script
const InstallerScriptName = "default-installer"
const InstallerScriptName = types.DefaultInstallerScriptName
// InstallerScriptName is the name of the by default populated, EC2
// installer script when agentless mode is enabled for a matcher
const InstallerScriptNameAgentless = "default-agentless-installer"
const InstallerScriptNameAgentless = types.DefaultInstallerScriptNameAgentless
// DefaultInstaller represents a the default installer script provided
// by teleport

View file

@ -16,6 +16,80 @@ limitations under the License.
package types
import (
"github.com/gravitational/trace"
"golang.org/x/exp/slices"
apiutils "github.com/gravitational/teleport/api/utils"
awsapiutils "github.com/gravitational/teleport/api/utils/aws"
)
const (
// IAMInviteTokenName is the name of the default Teleport IAM
// token to use when templating the script to be executed.
IAMInviteTokenName = "aws-discovery-iam-token"
// SSHDConfigPath is the path to the sshd config file to modify
// when using the agentless installer
SSHDConfigPath = "/etc/ssh/sshd_config"
// AWSInstallerDocument is the name of the default AWS document
// that will be called when executing the SSM command.
AWSInstallerDocument = "TeleportDiscoveryInstaller"
// AWSAgentlessInstallerDocument is the name of the default AWS document
// that will be called when executing the SSM command .
AWSAgentlessInstallerDocument = "TeleportAgentlessDiscoveryInstaller"
// AWSMatcherEC2 is the AWS matcher type for EC2 instances.
AWSMatcherEC2 = "ec2"
// AWSMatcherEKS is the AWS matcher type for AWS Kubernetes.
AWSMatcherEKS = "eks"
// AWSMatcherRDS is the AWS matcher type for RDS databases.
AWSMatcherRDS = "rds"
// AWSMatcherRDSProxy is the AWS matcher type for RDS Proxy databases.
AWSMatcherRDSProxy = "rdsproxy"
// AWSMatcherRedshift is the AWS matcher type for Redshift databases.
AWSMatcherRedshift = "redshift"
// AWSMatcherRedshiftServerless is the AWS matcher type for Redshift Serverless databases.
AWSMatcherRedshiftServerless = "redshift-serverless"
// AWSMatcherElastiCache is the AWS matcher type for ElastiCache databases.
AWSMatcherElastiCache = "elasticache"
// AWSMatcherMemoryDB is the AWS matcher type for MemoryDB databases.
AWSMatcherMemoryDB = "memorydb"
// AWSMatcherOpenSearch is the AWS matcher type for OpenSearch databases.
AWSMatcherOpenSearch = "opensearch"
)
// SupportedAWSMatchers is list of AWS services currently supported by the
// Teleport discovery service.
var SupportedAWSMatchers = append([]string{
AWSMatcherEC2,
AWSMatcherEKS,
}, SupportedAWSDatabaseMatchers...)
// SupportedAWSDatabaseMatchers is a list of the AWS databases currently
// supported by the Teleport discovery service.
var SupportedAWSDatabaseMatchers = []string{
AWSMatcherRDS,
AWSMatcherRDSProxy,
AWSMatcherRedshift,
AWSMatcherRedshiftServerless,
AWSMatcherElastiCache,
AWSMatcherMemoryDB,
AWSMatcherOpenSearch,
}
// RequireAWSIAMRolesAsUsersMatchers is a list of the AWS databases that
// require AWS IAM roles as database users.
// IMPORTANT: if you add database matchers for AWS keyspaces, OpenSearch, or
// DynamoDB discovery, add them here and in RequireAWSIAMRolesAsUsers in
// api/types.
var RequireAWSIAMRolesAsUsersMatchers = []string{
AWSMatcherRedshiftServerless,
AWSMatcherOpenSearch,
}
// GetTypes gets the types that the matcher can match.
func (m AWSMatcher) GetTypes() []string {
return m.Types
@ -29,7 +103,84 @@ func (m AWSMatcher) CopyWithTypes(t []string) Matcher {
}
// CheckAndSetDefaults that the matcher is correct and adds default values.
func (m AWSMatcher) CheckAndSetDefaults() error {
// TODO(marco): implement
func (m *AWSMatcher) CheckAndSetDefaults() error {
for _, matcherType := range m.Types {
if !slices.Contains(SupportedAWSMatchers, matcherType) {
return trace.BadParameter("discovery service type does not support %q, supported resource types are: %v",
matcherType, SupportedAWSMatchers)
}
}
if len(m.Types) == 0 {
return trace.BadParameter("discovery service requires at least one type")
}
if len(m.Regions) == 0 {
return trace.BadParameter("discovery service requires at least one region")
}
for _, region := range m.Regions {
if err := awsapiutils.IsValidRegion(region); err != nil {
return trace.BadParameter("discovery service does not support region %q", region)
}
}
if m.AssumeRole != nil {
if m.AssumeRole.RoleARN != "" {
if err := awsapiutils.CheckRoleARN(m.AssumeRole.RoleARN); err != nil {
return trace.BadParameter("invalid assume role: %v", err)
}
} else if m.AssumeRole.ExternalID != "" {
for _, t := range m.Types {
if !slices.Contains(RequireAWSIAMRolesAsUsersMatchers, t) {
return trace.BadParameter("discovery service AWS matcher assume_role_arn is empty, but has external_id %q",
m.AssumeRole.ExternalID)
}
}
}
}
if m.Tags == nil || len(m.Tags) == 0 {
m.Tags = map[string]apiutils.Strings{Wildcard: {Wildcard}}
}
if m.Params == nil {
m.Params = &InstallerParams{
InstallTeleport: true,
}
}
switch m.Params.JoinMethod {
case JoinMethodIAM, "":
m.Params.JoinMethod = JoinMethodIAM
default:
return trace.BadParameter("only IAM joining is supported for EC2 auto-discovery")
}
if m.Params.JoinToken == "" {
m.Params.JoinToken = IAMInviteTokenName
}
if m.Params.SSHDConfig == "" {
m.Params.SSHDConfig = SSHDConfigPath
}
if m.Params.ScriptName == "" {
m.Params.ScriptName = DefaultInstallerScriptNameAgentless
if m.Params.InstallTeleport {
m.Params.ScriptName = DefaultInstallerScriptName
}
}
if m.SSM == nil {
m.SSM = &AWSSSM{}
}
if m.SSM.DocumentName == "" {
m.SSM.DocumentName = AWSAgentlessInstallerDocument
if m.Params.InstallTeleport {
m.SSM.DocumentName = AWSInstallerDocument
}
}
return nil
}

View file

@ -0,0 +1,243 @@
// Copyright 2023 Gravitational, Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"testing"
"github.com/gravitational/trace"
"github.com/stretchr/testify/require"
)
func TestAWSMatcherCheckAndSetDefaults(t *testing.T) {
isBadParameterErr := func(tt require.TestingT, err error, i ...any) {
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err)
}
for _, tt := range []struct {
name string
in *AWSMatcher
errCheck require.ErrorAssertionFunc
expected *AWSMatcher
}{
{
name: "valid",
in: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
Tags: Labels{
"*": []string{"*"},
},
Params: &InstallerParams{
JoinMethod: JoinMethodIAM,
JoinToken: IAMInviteTokenName,
InstallTeleport: true,
ScriptName: DefaultInstallerScriptName,
SSHDConfig: SSHDConfigPath,
},
SSM: &AWSSSM{DocumentName: AWSInstallerDocument},
AssumeRole: &AssumeRole{
RoleARN: "arn:aws:iam:us-west-2:123456789012:role/MyRole001",
},
},
errCheck: require.NoError,
expected: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
Tags: Labels{
"*": []string{"*"},
},
Params: &InstallerParams{
JoinMethod: "iam",
JoinToken: "aws-discovery-iam-token",
InstallTeleport: true,
ScriptName: "default-installer",
SSHDConfig: "/etc/ssh/sshd_config",
},
SSM: &AWSSSM{DocumentName: "TeleportDiscoveryInstaller"},
AssumeRole: &AssumeRole{
RoleARN: "arn:aws:iam:us-west-2:123456789012:role/MyRole001",
},
},
},
{
name: "default values",
in: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
},
errCheck: require.NoError,
expected: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
Tags: Labels{
"*": []string{"*"},
},
Params: &InstallerParams{
JoinMethod: "iam",
JoinToken: "aws-discovery-iam-token",
InstallTeleport: true,
ScriptName: "default-installer",
SSHDConfig: "/etc/ssh/sshd_config",
},
SSM: &AWSSSM{DocumentName: "TeleportDiscoveryInstaller"},
},
},
{
name: "default values for agentless mode",
in: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
Params: &InstallerParams{
InstallTeleport: false,
},
},
errCheck: require.NoError,
expected: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
Tags: Labels{
"*": []string{"*"},
},
Params: &InstallerParams{
JoinMethod: "iam",
JoinToken: "aws-discovery-iam-token",
InstallTeleport: false,
ScriptName: "default-agentless-installer",
SSHDConfig: "/etc/ssh/sshd_config",
},
SSM: &AWSSSM{DocumentName: "TeleportAgentlessDiscoveryInstaller"},
},
},
{
name: "wildcard is invalid for types",
in: &AWSMatcher{
Types: []string{"*"},
Regions: []string{"eu-west-2"},
},
errCheck: isBadParameterErr,
},
{
name: "wildcard is invalid for regions",
in: &AWSMatcher{
Types: []string{"ec2", "rds"},
Regions: []string{"*"},
},
errCheck: isBadParameterErr,
},
{
name: "invalid type",
in: &AWSMatcher{
Types: []string{"ec2", "rds", "xpto"},
Regions: []string{"eu-west-2"},
},
errCheck: isBadParameterErr,
},
{
name: "invalid region",
in: &AWSMatcher{
Types: []string{"ec2", "rds", "xpto"},
Regions: []string{"pt-nope-4"},
},
errCheck: isBadParameterErr,
},
{
name: "invalid join method",
in: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
Params: &InstallerParams{
JoinMethod: "ec2",
},
},
errCheck: isBadParameterErr,
},
{
name: "no type",
in: &AWSMatcher{
Types: []string{},
Regions: []string{"eu-west-2"},
},
errCheck: isBadParameterErr,
},
{
name: "no region",
in: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{},
},
errCheck: isBadParameterErr,
},
{
name: "invalid assume role arn",
in: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
AssumeRole: &AssumeRole{
RoleARN: "arn:aws:not valid",
},
},
errCheck: isBadParameterErr,
},
{
name: "external id was set but assume role is missing",
in: &AWSMatcher{
Types: []string{"ec2"},
Regions: []string{"eu-west-2"},
AssumeRole: &AssumeRole{
ExternalID: "id123",
},
},
errCheck: isBadParameterErr,
},
{
name: "external id was set, assume role is missing but type allows it",
in: &AWSMatcher{
Types: []string{"redshift-serverless"},
Regions: []string{"eu-west-2"},
AssumeRole: &AssumeRole{
ExternalID: "id123",
},
},
errCheck: require.NoError,
expected: &AWSMatcher{
Types: []string{"redshift-serverless"},
Regions: []string{"eu-west-2"},
Tags: Labels{
"*": []string{"*"},
},
Params: &InstallerParams{
JoinMethod: "iam",
JoinToken: "aws-discovery-iam-token",
InstallTeleport: true,
ScriptName: "default-installer",
SSHDConfig: "/etc/ssh/sshd_config",
},
AssumeRole: &AssumeRole{
ExternalID: "id123",
},
SSM: &AWSSSM{DocumentName: "TeleportDiscoveryInstaller"},
},
},
} {
t.Run(tt.name, func(t *testing.T) {
err := tt.in.CheckAndSetDefaults()
tt.errCheck(t, err)
if tt.expected != nil {
require.Equal(t, tt.expected, tt.in)
}
})
}
}

View file

@ -16,6 +16,43 @@ limitations under the License.
package types
import (
"github.com/gravitational/trace"
"golang.org/x/exp/slices"
apiutils "github.com/gravitational/teleport/api/utils"
)
const (
// AzureInviteTokenName is the name of the default token to use
// when templating the script to be executed on Azure.
AzureInviteTokenName = "azure-discovery-token"
// AzureMatcherVM is the Azure matcher type for Azure VMs.
AzureMatcherVM = "vm"
// AzureMatcherKubernetes is the Azure matcher type for Azure Kubernetes.
AzureMatcherKubernetes = "aks"
// AzureMatcherMySQL is the Azure matcher type for Azure MySQL databases.
AzureMatcherMySQL = "mysql"
// AzureMatcherPostgres is the Azure matcher type for Azure Postgres databases.
AzureMatcherPostgres = "postgres"
// AzureMatcherRedis is the Azure matcher type for Azure Cache for Redis databases.
AzureMatcherRedis = "redis"
// AzureMatcherSQLServer is the Azure matcher type for SQL Server databases.
AzureMatcherSQLServer = "sqlserver"
)
// SupportedAzureMatchers is list of Azure services currently supported by the
// Teleport discovery service.
var SupportedAzureMatchers = []string{
AzureMatcherVM,
AzureMatcherKubernetes,
AzureMatcherMySQL,
AzureMatcherPostgres,
AzureMatcherRedis,
AzureMatcherSQLServer,
}
// GetTypes gets the types that the matcher can match.
func (m AzureMatcher) GetTypes() []string {
return m.Types
@ -29,7 +66,56 @@ func (m AzureMatcher) CopyWithTypes(t []string) Matcher {
}
// CheckAndSetDefaults that the matcher is correct and adds default values.
func (m AzureMatcher) CheckAndSetDefaults() error {
// TODO(marco): implement
func (m *AzureMatcher) CheckAndSetDefaults() error {
if len(m.Types) == 0 {
return trace.BadParameter("At least one Azure discovery service type must be specified, the supported resource types are: %v",
SupportedAzureMatchers)
}
for _, matcherType := range m.Types {
if !slices.Contains(SupportedAzureMatchers, matcherType) {
return trace.BadParameter("Azure discovery service type does not support %q resource type; supported resource types are: %v",
matcherType, SupportedAzureMatchers)
}
}
if slices.Contains(m.Types, AzureMatcherVM) {
if m.Params == nil {
m.Params = &InstallerParams{}
}
switch m.Params.JoinMethod {
case JoinMethodAzure, "":
m.Params.JoinMethod = JoinMethodAzure
default:
return trace.BadParameter("only Azure joining is supported for Azure auto-discovery")
}
if m.Params.JoinToken == "" {
m.Params.JoinToken = AzureInviteTokenName
}
if m.Params.ScriptName == "" {
m.Params.ScriptName = DefaultInstallerScriptName
}
}
if slices.Contains(m.Regions, Wildcard) || len(m.Regions) == 0 {
m.Regions = []string{Wildcard}
}
if slices.Contains(m.Subscriptions, Wildcard) || len(m.Subscriptions) == 0 {
m.Subscriptions = []string{Wildcard}
}
if slices.Contains(m.ResourceGroups, Wildcard) || len(m.ResourceGroups) == 0 {
m.ResourceGroups = []string{Wildcard}
}
if len(m.ResourceTags) == 0 {
m.ResourceTags = map[string]apiutils.Strings{
Wildcard: {Wildcard},
}
}
return nil
}

View file

@ -0,0 +1,129 @@
// Copyright 2023 Gravitational, Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"testing"
"github.com/gravitational/trace"
"github.com/stretchr/testify/require"
)
func TestAzureMatcherCheckAndSetDefaults(t *testing.T) {
isBadParameterErr := func(tt require.TestingT, err error, i ...any) {
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err)
}
for _, tt := range []struct {
name string
in *AzureMatcher
errCheck require.ErrorAssertionFunc
expected *AzureMatcher
}{
{
name: "valid",
in: &AzureMatcher{
Types: []string{"vm"},
Regions: []string{"westeurope"},
Subscriptions: []string{"s1", "s2"},
ResourceGroups: []string{"rg1"},
ResourceTags: Labels{
"x": []string{"y"},
},
Params: &InstallerParams{
JoinMethod: JoinMethodAzure,
JoinToken: AzureInviteTokenName,
ScriptName: DefaultInstallerScriptName,
},
},
errCheck: require.NoError,
expected: &AzureMatcher{
Types: []string{"vm"},
Regions: []string{"westeurope"},
Subscriptions: []string{"s1", "s2"},
ResourceGroups: []string{"rg1"},
ResourceTags: Labels{
"x": []string{"y"},
},
Params: &InstallerParams{
JoinMethod: "azure",
JoinToken: "azure-discovery-token",
ScriptName: "default-installer",
},
},
},
{
name: "default values",
in: &AzureMatcher{
Types: []string{"vm"},
},
errCheck: require.NoError,
expected: &AzureMatcher{
Types: []string{"vm"},
Regions: []string{"*"},
Subscriptions: []string{"*"},
ResourceGroups: []string{"*"},
ResourceTags: Labels{
"*": []string{"*"},
},
Params: &InstallerParams{
JoinMethod: "azure",
JoinToken: "azure-discovery-token",
ScriptName: "default-installer",
},
},
},
{
name: "wildcard is invalid for types",
in: &AzureMatcher{
Types: []string{"*"},
Regions: []string{"eu-west-2"},
},
errCheck: isBadParameterErr,
},
{
name: "invalid type",
in: &AzureMatcher{
Types: []string{"ec2"},
},
errCheck: isBadParameterErr,
},
{
name: "no type",
in: &AzureMatcher{
Types: []string{},
},
errCheck: isBadParameterErr,
},
{
name: "invalid join method",
in: &AzureMatcher{
Types: []string{"vm"},
Params: &InstallerParams{
JoinMethod: "invalid",
},
},
errCheck: isBadParameterErr,
},
} {
t.Run(tt.name, func(t *testing.T) {
err := tt.in.CheckAndSetDefaults()
tt.errCheck(t, err)
if tt.expected != nil {
require.Equal(t, tt.expected, tt.in)
}
})
}
}

View file

@ -16,6 +16,31 @@ limitations under the License.
package types
import (
"github.com/gravitational/trace"
"golang.org/x/exp/slices"
apiutils "github.com/gravitational/teleport/api/utils"
)
const (
// GCPInviteTokenName is the name of the default token to use
// when templating the script to be executed on GCP.
GCPInviteTokenName = "gcp-discovery-token"
// GCPMatcherKubernetes is the GCP matcher type for GCP kubernetes.
GCPMatcherKubernetes = "gke"
// GCPMatcherCompute is the GCP matcher for GCP VMs.
GCPMatcherCompute = "gce"
)
// SupportedGCPMatchers is list of GCP services currently supported by the
// Teleport discovery service.
var SupportedGCPMatchers = []string{
GCPMatcherKubernetes,
GCPMatcherCompute,
}
// GetTypes gets the types that the matcher can match.
func (m GCPMatcher) GetTypes() []string {
return m.Types
@ -38,7 +63,64 @@ func (m GCPMatcher) GetLabels() Labels {
}
// CheckAndSetDefaults that the matcher is correct and adds default values.
func (m GCPMatcher) CheckAndSetDefaults() error {
// TODO(marco): implement
func (m *GCPMatcher) CheckAndSetDefaults() error {
if len(m.Types) == 0 {
return trace.BadParameter("At least one GCP discovery service type must be specified, the supported resource types are: %v",
SupportedGCPMatchers)
}
for _, matcherType := range m.Types {
if !slices.Contains(SupportedGCPMatchers, matcherType) {
return trace.BadParameter("GCP discovery service type does not support %q resource type; supported resource types are: %v",
matcherType, SupportedGCPMatchers)
}
}
if slices.Contains(m.Types, GCPMatcherCompute) {
if m.Params == nil {
m.Params = &InstallerParams{}
}
switch m.Params.JoinMethod {
case JoinMethodGCP, "":
m.Params.JoinMethod = JoinMethodGCP
default:
return trace.BadParameter("only GCP joining is supported for GCP auto-discovery")
}
if m.Params.JoinToken == "" {
m.Params.JoinToken = GCPInviteTokenName
}
if m.Params.ScriptName == "" {
m.Params.ScriptName = DefaultInstallerScriptName
}
}
if slices.Contains(m.Locations, Wildcard) || len(m.Locations) == 0 {
m.Locations = []string{Wildcard}
}
if slices.Contains(m.ProjectIDs, Wildcard) {
return trace.BadParameter("GCP discovery service project_ids does not support wildcards; please specify at least one value in project_ids.")
}
if len(m.ProjectIDs) == 0 {
return trace.BadParameter("GCP discovery service project_ids does cannot be empty; please specify at least one value in project_ids.")
}
if len(m.Labels) > 0 && len(m.Tags) > 0 {
return trace.BadParameter("labels and tags should not both be set.")
}
if len(m.Tags) > 0 {
m.Labels = m.Tags
}
if len(m.Labels) == 0 {
m.Labels = map[string]apiutils.Strings{
Wildcard: {Wildcard},
}
}
return nil
}

View file

@ -0,0 +1,160 @@
// Copyright 2023 Gravitational, Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"testing"
"github.com/gravitational/trace"
"github.com/stretchr/testify/require"
)
func TestGCPMatcherCheckAndSetDefaults(t *testing.T) {
isBadParameterErr := func(tt require.TestingT, err error, i ...any) {
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err)
}
for _, tt := range []struct {
name string
in *GCPMatcher
errCheck require.ErrorAssertionFunc
expected *GCPMatcher
}{
{
name: "valid",
in: &GCPMatcher{
Types: []string{"gce"},
Locations: []string{"europe-west2"},
ProjectIDs: []string{"project01"},
Labels: Labels{
"x": []string{"y"},
},
Params: &InstallerParams{
JoinMethod: JoinMethodGCP,
JoinToken: GCPInviteTokenName,
ScriptName: DefaultInstallerScriptName,
},
},
errCheck: require.NoError,
expected: &GCPMatcher{
Types: []string{"gce"},
Locations: []string{"europe-west2"},
ProjectIDs: []string{"project01"},
Labels: Labels{
"x": []string{"y"},
},
Params: &InstallerParams{
JoinMethod: "gcp",
JoinToken: "gcp-discovery-token",
ScriptName: "default-installer",
},
},
},
{
name: "default values",
in: &GCPMatcher{
Types: []string{"gce"},
ProjectIDs: []string{"project01"},
},
errCheck: require.NoError,
expected: &GCPMatcher{
Types: []string{"gce"},
Locations: []string{"*"},
ProjectIDs: []string{"project01"},
Labels: Labels{
"*": []string{"*"},
},
Params: &InstallerParams{
JoinMethod: "gcp",
JoinToken: "gcp-discovery-token",
ScriptName: "default-installer",
},
},
},
{
name: "wildcard is invalid for types",
in: &GCPMatcher{
Types: []string{"*"},
ProjectIDs: []string{"project01"},
},
errCheck: isBadParameterErr,
},
{
name: "wildcard is invalid for project ids",
in: &GCPMatcher{
Types: []string{"gce"},
ProjectIDs: []string{"*"},
},
errCheck: isBadParameterErr,
},
{
name: "invalid type",
in: &GCPMatcher{
Types: []string{"invalid"},
ProjectIDs: []string{"project01"},
},
errCheck: isBadParameterErr,
},
{
name: "invalid join method",
in: &GCPMatcher{
Types: []string{"gce"},
ProjectIDs: []string{"project01"},
Params: &InstallerParams{
JoinMethod: "invalid",
},
},
errCheck: isBadParameterErr,
},
{
name: "no type",
in: &GCPMatcher{
Types: []string{},
ProjectIDs: []string{"project01"},
},
errCheck: isBadParameterErr,
},
{
name: "no project id",
in: &GCPMatcher{
Types: []string{"gce"},
ProjectIDs: []string{},
},
errCheck: isBadParameterErr,
},
{
name: "error if both labels and tags are set",
in: &GCPMatcher{
Types: []string{"gce"},
ProjectIDs: []string{"project001"},
Labels: Labels{
"*": []string{"*"},
},
Tags: Labels{
"*": []string{"*"},
},
},
errCheck: isBadParameterErr,
},
} {
t.Run(tt.name, func(t *testing.T) {
err := tt.in.CheckAndSetDefaults()
tt.errCheck(t, err)
if tt.expected != nil {
require.Equal(t, tt.expected, tt.in)
}
})
}
}

View file

@ -16,8 +16,44 @@ limitations under the License.
package types
import (
"github.com/gravitational/trace"
"golang.org/x/exp/slices"
apiutils "github.com/gravitational/teleport/api/utils"
)
const (
// KubernetesMatchersApp is app matcher type for Kubernetes services
KubernetesMatchersApp = "app"
)
// SupportedKubernetesMatchers is a list of Kubernetes matchers supported by
// Teleport discovery service
var SupportedKubernetesMatchers = []string{
KubernetesMatchersApp,
}
// CheckAndSetDefaults that the matcher is correct and adds default values.
func (m KubernetesMatcher) CheckAndSetDefaults() error {
// TODO(marco): implement
func (m *KubernetesMatcher) CheckAndSetDefaults() error {
for _, t := range m.Types {
if !slices.Contains(SupportedKubernetesMatchers, t) {
return trace.BadParameter("Kubernetes discovery does not support %q resource type; supported resource types are: %v",
t, SupportedKubernetesMatchers)
}
}
if len(m.Types) == 0 {
m.Types = []string{KubernetesMatchersApp}
}
if len(m.Namespaces) == 0 {
m.Namespaces = []string{Wildcard}
}
if len(m.Labels) == 0 {
m.Labels = map[string]apiutils.Strings{Wildcard: {Wildcard}}
}
return nil
}

View file

@ -0,0 +1,88 @@
// Copyright 2023 Gravitational, Inc
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"testing"
"github.com/gravitational/trace"
"github.com/stretchr/testify/require"
)
func TestKubeMatcherCheckAndSetDefaults(t *testing.T) {
isBadParameterErr := func(tt require.TestingT, err error, i ...any) {
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err)
}
for _, tt := range []struct {
name string
in *KubernetesMatcher
errCheck require.ErrorAssertionFunc
expected *KubernetesMatcher
}{
{
name: "valid",
in: &KubernetesMatcher{
Types: []string{"app"},
Namespaces: []string{"default"},
Labels: Labels{
"x": []string{"y"},
},
},
errCheck: require.NoError,
expected: &KubernetesMatcher{
Types: []string{"app"},
Namespaces: []string{"default"},
Labels: Labels{
"x": []string{"y"},
},
},
},
{
name: "default values",
in: &KubernetesMatcher{},
errCheck: require.NoError,
expected: &KubernetesMatcher{
Types: []string{"app"},
Namespaces: []string{"*"},
Labels: Labels{
"*": []string{"*"},
},
},
},
{
name: "wildcard is invalid for types",
in: &KubernetesMatcher{
Types: []string{"*"},
},
errCheck: isBadParameterErr,
},
{
name: "invalid type",
in: &KubernetesMatcher{
Types: []string{"db"},
},
errCheck: isBadParameterErr,
},
} {
t.Run(tt.name, func(t *testing.T) {
err := tt.in.CheckAndSetDefaults()
tt.errCheck(t, err)
if tt.expected != nil {
require.Equal(t, tt.expected, tt.in)
}
})
}
}

View file

@ -18,6 +18,7 @@ package aws
import (
"regexp"
"strings"
"github.com/gravitational/trace"
)
@ -61,6 +62,45 @@ func IsValidRegion(region string) error {
return trace.BadParameter("region %q is invalid", region)
}
const (
arnDelimiter = ":"
arnPrefix = "arn:"
arnSections = 6
sectionService = 2 // arn:<partition>:<service>:...
sectionAccount = 4 // arn:<partition>:<service>:<region>:<accountid>:...
sectionResource = 5 // arn:<partition>:<service>:<region>:<accountid>:<resource>
iamServiceName = "iam"
)
// CheckRoleARN returns whether a string is a valid IAM Role ARN.
// Example role ARN: arn:aws:iam::123456789012:role/some-role-name
func CheckRoleARN(arn string) error {
if !strings.HasPrefix(arn, arnPrefix) {
return trace.BadParameter("arn: invalid prefix: %q", arn)
}
sections := strings.SplitN(arn, arnDelimiter, arnSections)
if len(sections) != arnSections {
return trace.BadParameter("arn: not enough sections: %q", arn)
}
resourceParts := strings.SplitN(sections[sectionResource], "/", 2)
if resourceParts[0] != "role" || sections[sectionService] != iamServiceName {
return trace.BadParameter("%q is not an AWS IAM role ARN", arn)
}
if len(resourceParts) < 2 || resourceParts[1] == "" {
return trace.BadParameter("%q is missing AWS IAM role name", arn)
}
if err := IsValidAccountID(sections[sectionAccount]); err != nil {
return trace.BadParameter("%q invalid account ID: %v", arn, err)
}
return nil
}
var (
// matchRoleName is a regex that matches against AWS IAM Role Names.
matchRoleName = regexp.MustCompile(`^[\w+=,.@-]+$`).MatchString

View file

@ -179,3 +179,70 @@ func TestIsValidRegion(t *testing.T) {
})
}
}
func TestCheckRoleARN(t *testing.T) {
isBadParamErrFn := func(tt require.TestingT, err error, i ...any) {
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err)
}
for _, tt := range []struct {
name string
arn string
errCheck require.ErrorAssertionFunc
}{
{
name: "valid",
arn: "arn:aws:iam:us-west-2:123456789012:role/foo/bar",
errCheck: require.NoError,
},
{
name: "empty string",
arn: "",
errCheck: isBadParamErrFn,
},
{
name: "arn identifier but no other section",
arn: "arn:nil",
errCheck: isBadParamErrFn,
},
{
name: "valid with resource that has spaces",
arn: "arn:aws:iam:us-west-2:123456789012:role/foo bar",
errCheck: require.NoError,
},
{
name: "valid when resource section has :",
arn: "arn:aws:iam:us-west-2:123456789012:role/foo bar:a",
errCheck: require.NoError,
},
{
name: "invalid when resource is missing",
arn: "arn:aws:iam:us-west-2:123456789012",
errCheck: isBadParamErrFn,
},
{
name: "valid even if region is missing",
arn: "arn:aws:iam::123456789012:role/foo bar",
errCheck: require.NoError,
},
{
name: "invalid when the resource is not role",
arn: "arn:aws:iam::123456789012:user/foo bar",
errCheck: isBadParamErrFn,
},
{
name: "invalid when the resource is of type role, but role name section is missing",
arn: "arn:aws:iam::123456789012:role",
errCheck: isBadParamErrFn,
},
{
name: "invalid when the resource is of type role, but role is empty",
arn: "arn:aws:iam::123456789012:role/",
errCheck: isBadParamErrFn,
},
} {
t.Run(tt.name, func(t *testing.T) {
tt.errCheck(t, CheckRoleARN(tt.arn))
})
}
}

View file

@ -215,7 +215,7 @@ func withKubeService(t *testing.T, matchers ...services.ResourceMatcher) testOpt
func withKubeDiscoveryService(t *testing.T, tags types.Labels) testOptionsFunc {
t.Helper()
return withDiscoveryService(t, "kube-e2e-test", types.AWSMatcher{
Types: []string{services.AWSMatcherEKS},
Types: []string{types.AWSMatcherEKS},
Tags: tags,
Regions: []string{os.Getenv(awsRegionEnv)},
AssumeRole: &types.AssumeRole{

View file

@ -65,7 +65,7 @@ func awsDBDiscoveryUnmatched(t *testing.T) {
cluster := createTeleportCluster(t,
withSingleProxyPort(t),
withDiscoveryService(t, "db-e2e-test", types.AWSMatcher{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Tags: types.Labels{
// This label should not match.
"env": {"tag_not_found"},
@ -110,7 +110,7 @@ func awsDBDiscoveryMatched(t *testing.T) {
cluster := createTeleportCluster(t,
withSingleProxyPort(t),
withDiscoveryService(t, "db-e2e-test", types.AWSMatcher{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Tags: mustGetDiscoveryMatcherLabels(t),
Regions: []string{awsRegion},
AssumeRole: &types.AssumeRole{

View file

@ -1361,9 +1361,21 @@ func applyDiscoveryConfig(fc *FileConfig, cfg *servicecfg.Config) error {
cfg.Discovery.DiscoveryGroup = fc.Discovery.DiscoveryGroup
cfg.Discovery.PollInterval = fc.Discovery.PollInterval
for _, matcher := range fc.Discovery.AWSMatchers {
installParams, err := matcher.InstallParams.Parse()
if err != nil {
return trace.Wrap(err)
var err error
var installParams *types.InstallerParams
if matcher.InstallParams != nil {
installParams, err = matcher.InstallParams.parse()
if err != nil {
return trace.Wrap(err)
}
}
var assumeRole *types.AssumeRole
if matcher.AssumeRoleARN != "" || matcher.ExternalID != "" {
assumeRole = &types.AssumeRole{
RoleARN: matcher.AssumeRoleARN,
ExternalID: matcher.ExternalID,
}
}
for _, region := range matcher.Regions {
@ -1377,73 +1389,96 @@ func applyDiscoveryConfig(fc *FileConfig, cfg *servicecfg.Config) error {
}
}
cfg.Discovery.AWSMatchers = append(cfg.Discovery.AWSMatchers,
types.AWSMatcher{
Types: matcher.Types,
Regions: matcher.Regions,
AssumeRole: &types.AssumeRole{
RoleARN: matcher.AssumeRoleARN,
ExternalID: matcher.ExternalID,
},
Tags: matcher.Tags,
Params: &installParams,
SSM: &types.AWSSSM{DocumentName: matcher.SSM.DocumentName},
})
serviceMatcher := types.AWSMatcher{
Types: matcher.Types,
Regions: matcher.Regions,
AssumeRole: assumeRole,
Tags: matcher.Tags,
Params: installParams,
SSM: &types.AWSSSM{DocumentName: matcher.SSM.DocumentName},
}
if err := serviceMatcher.CheckAndSetDefaults(); err != nil {
return trace.Wrap(err)
}
cfg.Discovery.AWSMatchers = append(cfg.Discovery.AWSMatchers, serviceMatcher)
}
for _, matcher := range fc.Discovery.AzureMatchers {
m := types.AzureMatcher{
Subscriptions: matcher.Subscriptions,
ResourceGroups: matcher.ResourceGroups,
Types: matcher.Types,
Regions: matcher.Regions,
ResourceTags: matcher.ResourceTags,
}
var installerParams *types.InstallerParams
if matcher.InstallParams != nil {
m.Params = &types.InstallerParams{
installerParams = &types.InstallerParams{
JoinMethod: matcher.InstallParams.JoinParams.Method,
JoinToken: matcher.InstallParams.JoinParams.TokenName,
ScriptName: matcher.InstallParams.ScriptName,
PublicProxyAddr: getInstallerProxyAddr(matcher.InstallParams, fc),
}
if matcher.InstallParams.Azure != nil {
m.Params.Azure = &types.AzureInstallerParams{
installerParams.Azure = &types.AzureInstallerParams{
ClientID: matcher.InstallParams.Azure.ClientID,
}
}
}
cfg.Discovery.AzureMatchers = append(cfg.Discovery.AzureMatchers, m)
serviceMatcher := types.AzureMatcher{
Subscriptions: matcher.Subscriptions,
ResourceGroups: matcher.ResourceGroups,
Types: matcher.Types,
Regions: matcher.Regions,
ResourceTags: matcher.ResourceTags,
Params: installerParams,
}
if err := serviceMatcher.CheckAndSetDefaults(); err != nil {
return trace.Wrap(err)
}
cfg.Discovery.AzureMatchers = append(cfg.Discovery.AzureMatchers, serviceMatcher)
}
for _, matcher := range fc.Discovery.GCPMatchers {
m := types.GCPMatcher{
Types: matcher.Types,
Locations: matcher.Locations,
Labels: matcher.Labels,
Tags: matcher.Tags,
ProjectIDs: matcher.ProjectIDs,
ServiceAccounts: matcher.ServiceAccounts,
}
var installerParams *types.InstallerParams
if matcher.InstallParams != nil {
m.Params = &types.InstallerParams{
installerParams = &types.InstallerParams{
JoinMethod: matcher.InstallParams.JoinParams.Method,
JoinToken: matcher.InstallParams.JoinParams.TokenName,
ScriptName: matcher.InstallParams.ScriptName,
PublicProxyAddr: getInstallerProxyAddr(matcher.InstallParams, fc),
}
}
cfg.Discovery.GCPMatchers = append(cfg.Discovery.GCPMatchers, m)
serviceMatcher := types.GCPMatcher{
Types: matcher.Types,
Locations: matcher.Locations,
Labels: matcher.Labels,
Tags: matcher.Tags,
ProjectIDs: matcher.ProjectIDs,
ServiceAccounts: matcher.ServiceAccounts,
Params: installerParams,
}
if err := serviceMatcher.CheckAndSetDefaults(); err != nil {
return trace.Wrap(err)
}
cfg.Discovery.GCPMatchers = append(cfg.Discovery.GCPMatchers, serviceMatcher)
}
if len(fc.Discovery.KubernetesMatchers) > 0 {
if fc.Discovery.DiscoveryGroup == "" {
// TODO(anton): add link to documentation when it's available
return trace.BadParameter(`parameter 'discovery_group' should be defined for discovery service if
kubernetes matchers are present`)
}
}
for _, matcher := range fc.Discovery.KubernetesMatchers {
cfg.Discovery.KubernetesMatchers = append(cfg.Discovery.KubernetesMatchers,
types.KubernetesMatcher{
Types: matcher.Types,
Namespaces: matcher.Namespaces,
Labels: matcher.Labels,
},
)
serviceMatcher := types.KubernetesMatcher{
Types: matcher.Types,
Namespaces: matcher.Namespaces,
Labels: matcher.Labels,
}
if err := serviceMatcher.CheckAndSetDefaults(); err != nil {
return trace.Wrap(err)
}
cfg.Discovery.KubernetesMatchers = append(cfg.Discovery.KubernetesMatchers, serviceMatcher)
}
return nil

View file

@ -40,6 +40,7 @@ import (
"github.com/gravitational/teleport/api/constants"
apidefaults "github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/installers"
apiutils "github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/lib"
"github.com/gravitational/teleport/lib/auth/keystore"
@ -360,15 +361,6 @@ func TestConfigReading(t *testing.T) {
},
AssumeRoleARN: "arn:aws:iam::123456789012:role/DBDiscoverer",
ExternalID: "externalID123",
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: "aws-discovery-iam-token",
Method: "iam",
},
SSHDConfig: "/etc/ssh/sshd_config",
ScriptName: "default-installer",
},
SSM: AWSSSM{DocumentName: "TeleportDiscoveryInstaller"},
},
},
AzureMatchers: []AzureMatcher{
@ -903,9 +895,9 @@ SREzU8onbBsjMg9QDiSf5oJLKvd/Ren+zGY7
require.Equal(t, cfg.Discovery.AWSMatchers[0].Params, &types.InstallerParams{
InstallTeleport: true,
JoinMethod: "iam",
JoinToken: defaults.IAMInviteTokenName,
JoinToken: types.IAMInviteTokenName,
ScriptName: "default-installer",
SSHDConfig: defaults.SSHDConfigPath,
SSHDConfig: types.SSHDConfigPath,
})
require.True(t, cfg.Okta.Enabled)
@ -3771,6 +3763,9 @@ func TestApplyDiscoveryConfig(t *testing.T) {
ClientID: "abcd1234",
},
},
Regions: []string{"*"},
ResourceTags: types.Labels{"*": []string{"*"}},
ResourceGroups: []string{"*"},
},
},
},
@ -3789,8 +3784,11 @@ func TestApplyDiscoveryConfig(t *testing.T) {
Enabled: true,
AzureMatchers: []types.AzureMatcher{
{
Subscriptions: []string{"abcd"},
Types: []string{"aks"},
Subscriptions: []string{"abcd"},
Types: []string{"aks"},
Regions: []string{"*"},
ResourceTags: types.Labels{"*": []string{"*"}},
ResourceGroups: []string{"*"},
},
},
},
@ -4197,3 +4195,534 @@ func TestGetInstallerProxyAddr(t *testing.T) {
})
}
}
func TestDiscoveryConfig(t *testing.T) {
t.Parallel()
testCases := []struct {
desc string
mutate func(cfgMap)
expectError require.ErrorAssertionFunc
expectEnabled require.BoolAssertionFunc
expectedTotalMatchers int
expectedAWSMatchers []types.AWSMatcher
expectedAzureMatchers []types.AzureMatcher
expectedGCPMatchers []types.GCPMatcher
}{
{
desc: "default",
mutate: func(cfgMap) {},
expectError: require.NoError,
expectEnabled: require.False,
},
{
desc: "GCP section without project_ids",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gke"},
},
}
},
},
{
desc: "GCP section is filled with defaults",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gke"},
"project_ids": []string{"p1", "p2"},
},
}
},
expectedGCPMatchers: []types.GCPMatcher{{
Types: []string{"gke"},
Locations: []string{"*"},
Labels: map[string]apiutils.Strings{
"*": []string{"*"},
},
ProjectIDs: []string{"p1", "p2"},
}},
},
{
desc: "GCP section is filled",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gke"},
"locations": []string{"eucentral1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"project_ids": []string{"p1", "p2"},
},
}
},
expectedGCPMatchers: []types.GCPMatcher{{
Types: []string{"gke"},
Locations: []string{"eucentral1"},
Labels: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
ProjectIDs: []string{"p1", "p2"},
}},
},
{
desc: "GCP section is filled with installer",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gce"},
"locations": []string{"eucentral1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"project_ids": []string{"p1", "p2"},
"service_accounts": []string{"a@example.com", "b@example.com"},
},
}
},
expectedGCPMatchers: []types.GCPMatcher{{
Types: []string{"gce"},
Locations: []string{"eucentral1"},
Labels: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
ProjectIDs: []string{"p1", "p2"},
ServiceAccounts: []string{"a@example.com", "b@example.com"},
Params: &types.InstallerParams{
JoinMethod: types.JoinMethodGCP,
JoinToken: types.GCPInviteTokenName,
ScriptName: installers.InstallerScriptName,
},
}},
},
{
desc: "Azure section is filled with defaults (aks)",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{
"types": []string{"aks"},
},
}
},
expectedAzureMatchers: []types.AzureMatcher{{
Types: []string{"aks"},
Regions: []string{"*"},
ResourceTags: map[string]apiutils.Strings{
"*": []string{"*"},
},
Subscriptions: []string{"*"},
ResourceGroups: []string{"*"},
}},
},
{
desc: "Azure section is filled with values",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{
"types": []string{"aks"},
"regions": []string{"eucentral1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"subscriptions": []string{"sub1", "sub2"},
"resource_groups": []string{"group1", "group2"},
},
}
},
expectedAzureMatchers: []types.AzureMatcher{{
Types: []string{"aks"},
Regions: []string{"eucentral1"},
ResourceTags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Subscriptions: []string{"sub1", "sub2"},
ResourceGroups: []string{"group1", "group2"},
}},
},
{
desc: "AWS section is filled with defaults",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"ec2"},
"regions": []string{"eu-central-1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedAWSMatchers: []types.AWSMatcher{{
Types: []string{"ec2"},
Regions: []string{"eu-central-1"},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Params: &types.InstallerParams{
JoinMethod: types.JoinMethodIAM,
JoinToken: types.IAMInviteTokenName,
SSHDConfig: "/etc/ssh/sshd_config",
ScriptName: installers.InstallerScriptName,
InstallTeleport: true,
},
SSM: &types.AWSSSM{DocumentName: types.AWSInstallerDocument},
}},
},
{
desc: "AWS section is filled with custom configs",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"ec2"},
"regions": []string{"eu-central-1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"install": cfgMap{
"join_params": cfgMap{
"token_name": "hello-iam-a-token",
"method": "iam",
},
"script_name": "installer-custom",
},
"ssm": cfgMap{
"document_name": "hello_document",
},
"assume_role_arn": "arn:aws:iam::123456789012:role/DBDiscoverer",
"external_id": "externalID123",
},
}
},
expectedAWSMatchers: []types.AWSMatcher{{
Types: []string{"ec2"},
Regions: []string{"eu-central-1"},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Params: &types.InstallerParams{
JoinMethod: types.JoinMethodIAM,
JoinToken: "hello-iam-a-token",
SSHDConfig: "/etc/ssh/sshd_config",
ScriptName: "installer-custom",
InstallTeleport: true,
},
SSM: &types.AWSSSM{DocumentName: "hello_document"},
AssumeRole: &types.AssumeRole{
RoleARN: "arn:aws:iam::123456789012:role/DBDiscoverer",
ExternalID: "externalID123",
},
}},
},
{
desc: "AWS section is filled with invalid region",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"ec2"},
"regions": []string{"*"},
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
},
{
desc: "AWS section is filled with invalid join method",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"install": cfgMap{
"join_params": cfgMap{
"token_name": "hello-iam-a-token",
"method": "token",
},
},
},
}
},
},
{
desc: "AWS section is filled with external_id but empty assume_role_arn",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"rds"},
"regions": []string{"us-west-1"},
"assume_role_arn": "",
"external_id": "externalid123",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
},
{
desc: "AWS section is filled with external_id but empty assume_role_arn is ok for redshift serverless",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"redshift-serverless"},
"regions": []string{"us-west-1"},
"assume_role_arn": "",
"external_id": "externalid123",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedAWSMatchers: []types.AWSMatcher{{
Types: []string{"redshift-serverless"},
Regions: []string{"us-west-1"},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Params: &types.InstallerParams{
JoinMethod: types.JoinMethodIAM,
JoinToken: "aws-discovery-iam-token",
SSHDConfig: "/etc/ssh/sshd_config",
ScriptName: "default-installer",
InstallTeleport: true,
},
SSM: &types.AWSSSM{DocumentName: "TeleportDiscoveryInstaller"},
AssumeRole: &types.AssumeRole{
RoleARN: "",
ExternalID: "externalid123",
},
}},
},
{
desc: "AWS section is filled with invalid assume_role_arn",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"rds"},
"regions": []string{"us-west-1"},
"assume_role_arn": "foobar",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
},
{
desc: "AWS section is filled with assume_role_arn that is not an iam ARN",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"rds"},
"regions": []string{"us-west-1"},
"assume_role_arn": "arn:aws:sts::123456789012:federated-user/Alice",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
},
{
desc: "AWS section is filled with no token",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"ec2"},
"regions": []string{"eu-west-1"},
"install": cfgMap{
"join_params": cfgMap{
"method": "iam",
},
},
},
}
},
expectedAWSMatchers: []types.AWSMatcher{{
Types: []string{"ec2"},
SSM: &types.AWSSSM{
DocumentName: types.AWSInstallerDocument,
},
Regions: []string{"eu-west-1"},
Tags: map[string]apiutils.Strings{"*": {"*"}},
Params: &types.InstallerParams{
JoinMethod: types.JoinMethodIAM,
JoinToken: types.IAMInviteTokenName,
ScriptName: installers.InstallerScriptName,
SSHDConfig: "/etc/ssh/sshd_config",
InstallTeleport: true,
},
}},
},
{
desc: "Azure section is filled with defaults (vm)",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{
"types": []string{"vm"},
"regions": []string{"westcentralus"},
"resource_groups": []string{"rg1"},
"subscriptions": []string{"88888888-8888-8888-8888-888888888888"},
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedAzureMatchers: []types.AzureMatcher{{
Types: []string{"vm"},
Regions: []string{"westcentralus"},
ResourceGroups: []string{"rg1"},
Subscriptions: []string{"88888888-8888-8888-8888-888888888888"},
ResourceTags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Params: &types.InstallerParams{
JoinMethod: "azure",
JoinToken: "azure-discovery-token",
ScriptName: "default-installer",
},
}},
},
{
desc: "Azure section is filled with custom config",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{"types": []string{"vm"},
"regions": []string{"westcentralus"},
"resource_groups": []string{"rg1"},
"subscriptions": []string{"88888888-8888-8888-8888-888888888888"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"install": cfgMap{
"join_params": cfgMap{
"token_name": "custom-azure-token",
"method": "azure",
},
"script_name": "custom-installer",
"public_proxy_addr": "teleport.example.com",
},
},
}
},
expectedAzureMatchers: []types.AzureMatcher{{
Types: []string{"vm"},
Regions: []string{"westcentralus"},
ResourceGroups: []string{"rg1"},
Subscriptions: []string{"88888888-8888-8888-8888-888888888888"},
ResourceTags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Params: &types.InstallerParams{
JoinMethod: "azure",
JoinToken: "custom-azure-token",
ScriptName: "custom-installer",
PublicProxyAddr: "teleport.example.com",
},
}},
},
{
desc: "Azure section is filled with invalid join method",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{"types": []string{"vm"},
"regions": []string{"westcentralus"},
"resource_groups": []string{"rg1"},
"subscriptions": []string{"88888888-8888-8888-8888-888888888888"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"install": cfgMap{
"join_params": cfgMap{
"token_name": "custom-azure-token",
"method": "token",
},
},
},
}
},
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
text := bytes.NewBuffer(editConfig(t, testCase.mutate))
fc, err := ReadConfig(text)
require.NoError(t, err)
cfg := servicecfg.MakeDefaultConfig()
err = ApplyFileConfig(fc, cfg)
testCase.expectError(t, err)
if cfg == nil {
return
}
testCase.expectEnabled(t, cfg.Discovery.Enabled)
require.Equal(t, testCase.expectedAWSMatchers, cfg.Discovery.AWSMatchers)
require.Equal(t, testCase.expectedAzureMatchers, cfg.Discovery.AzureMatchers)
require.Equal(t, testCase.expectedGCPMatchers, cfg.Discovery.GCPMatchers)
})
}
}

View file

@ -41,9 +41,7 @@ import (
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/installers"
apiutils "github.com/gravitational/teleport/api/utils"
awsapiutils "github.com/gravitational/teleport/api/utils/aws"
"github.com/gravitational/teleport/api/utils/tlsutils"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/client"
@ -52,7 +50,6 @@ import (
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/sshutils/x11"
"github.com/gravitational/teleport/lib/utils"
awsutils "github.com/gravitational/teleport/lib/utils/aws"
)
// FileConfig structure represents the teleport configuration stored in a config file
@ -485,311 +482,6 @@ func (conf *FileConfig) CheckAndSetDefaults() error {
}
}
if err := checkAndSetDefaultsForAWSMatchers(conf.Discovery.AWSMatchers); err != nil {
return trace.Wrap(err)
}
if err := checkAndSetDefaultsForAzureMatchers(conf.Discovery.AzureMatchers); err != nil {
return trace.Wrap(err)
}
if err := checkAndSetDefaultsForGCPMatchers(conf.Discovery.GCPMatchers); err != nil {
return trace.Wrap(err)
}
if len(conf.Discovery.KubernetesMatchers) > 0 {
if conf.Discovery.DiscoveryGroup == "" {
// TODO(anton): add link to documentation when it's available
return trace.BadParameter(`parameter 'discovery_group' should be defined for discovery service if
kubernetes matchers are present`)
}
if err := checkAndSetDefaultsForKubeMatchers(conf.Discovery.KubernetesMatchers); err != nil {
return trace.Wrap(err)
}
}
return nil
}
// checkAndSetDefaultsForAWSMatchers sets the default values for discovery AWS matchers
// and validates the provided types.
func checkAndSetDefaultsForAWSMatchers(matcherInput []AWSMatcher) error {
for i := range matcherInput {
matcher := &matcherInput[i]
for _, matcherType := range matcher.Types {
if !slices.Contains(services.SupportedAWSMatchers, matcherType) {
return trace.BadParameter("discovery service type does not support %q, supported resource types are: %v",
matcherType, services.SupportedAWSMatchers)
}
}
if len(matcher.Regions) == 0 {
return trace.BadParameter("discovery service requires at least one region; supported regions are: %v",
awsutils.GetKnownRegions())
}
for _, region := range matcher.Regions {
if err := awsapiutils.IsValidRegion(region); err != nil {
return trace.BadParameter("discovery service does not support region %q; supported regions are: %v",
region, awsutils.GetKnownRegions())
}
}
if matcher.AssumeRoleARN != "" {
_, err := awsutils.ParseRoleARN(matcher.AssumeRoleARN)
if err != nil {
return trace.Wrap(err, "discovery service AWS matcher assume_role_arn is invalid")
}
} else if matcher.ExternalID != "" {
for _, t := range matcher.Types {
if !slices.Contains(services.RequireAWSIAMRolesAsUsersMatchers, t) {
return trace.BadParameter("discovery service AWS matcher assume_role_arn is empty, but has external_id %q",
matcher.ExternalID)
}
}
}
if matcher.Tags == nil || len(matcher.Tags) == 0 {
matcher.Tags = map[string]apiutils.Strings{types.Wildcard: {types.Wildcard}}
}
var installParams types.InstallerParams
var err error
if matcher.InstallParams == nil {
matcher.InstallParams = &InstallParams{
JoinParams: JoinParams{
TokenName: defaults.IAMInviteTokenName,
Method: types.JoinMethodIAM,
},
ScriptName: installers.InstallerScriptName,
InstallTeleport: "",
SSHDConfig: defaults.SSHDConfigPath,
}
installParams, err = matcher.InstallParams.Parse()
if err != nil {
return trace.Wrap(err)
}
} else {
if method := matcher.InstallParams.JoinParams.Method; method == "" {
matcher.InstallParams.JoinParams.Method = types.JoinMethodIAM
} else if method != types.JoinMethodIAM {
return trace.BadParameter("only IAM joining is supported for EC2 auto-discovery")
}
if matcher.InstallParams.JoinParams.TokenName == "" {
matcher.InstallParams.JoinParams.TokenName = defaults.IAMInviteTokenName
}
if matcher.InstallParams.SSHDConfig == "" {
matcher.InstallParams.SSHDConfig = defaults.SSHDConfigPath
}
installParams, err = matcher.InstallParams.Parse()
if err != nil {
return trace.Wrap(err)
}
if installer := matcher.InstallParams.ScriptName; installer == "" {
if installParams.InstallTeleport {
matcher.InstallParams.ScriptName = installers.InstallerScriptName
} else {
matcher.InstallParams.ScriptName = installers.InstallerScriptNameAgentless
}
}
}
if matcher.SSM.DocumentName == "" {
if installParams.InstallTeleport {
matcher.SSM.DocumentName = defaults.AWSInstallerDocument
} else {
matcher.SSM.DocumentName = defaults.AWSAgentlessInstallerDocument
}
}
}
return nil
}
// checkAndSetDefaultsForAzureMatchers sets the default values for discovery Azure matchers
// and validates the provided types.
func checkAndSetDefaultsForAzureMatchers(matcherInput []AzureMatcher) error {
for i := range matcherInput {
matcher := &matcherInput[i]
if len(matcher.Types) == 0 {
return trace.BadParameter("At least one Azure discovery service type must be specified, the supported resource types are: %v",
services.SupportedAzureMatchers)
}
for _, matcherType := range matcher.Types {
if !slices.Contains(services.SupportedAzureMatchers, matcherType) {
return trace.BadParameter("Azure discovery service type does not support %q resource type; supported resource types are: %v",
matcherType, services.SupportedAzureMatchers)
}
}
if slices.Contains(matcher.Types, services.AzureMatcherVM) {
if err := checkAndSetDefaultsForAzureInstaller(matcher); err != nil {
return trace.Wrap(err)
}
}
if slices.Contains(matcher.Regions, types.Wildcard) || len(matcher.Regions) == 0 {
matcher.Regions = []string{types.Wildcard}
}
if slices.Contains(matcher.Subscriptions, types.Wildcard) || len(matcher.Subscriptions) == 0 {
matcher.Subscriptions = []string{types.Wildcard}
}
if slices.Contains(matcher.ResourceGroups, types.Wildcard) || len(matcher.ResourceGroups) == 0 {
matcher.ResourceGroups = []string{types.Wildcard}
}
if len(matcher.ResourceTags) == 0 {
matcher.ResourceTags = map[string]apiutils.Strings{
types.Wildcard: {types.Wildcard},
}
}
}
return nil
}
func checkAndSetDefaultsForAzureInstaller(matcher *AzureMatcher) error {
if matcher.InstallParams == nil {
matcher.InstallParams = &InstallParams{
JoinParams: JoinParams{
TokenName: defaults.AzureInviteTokenName,
Method: types.JoinMethodAzure,
},
ScriptName: installers.InstallerScriptName,
}
return nil
}
switch matcher.InstallParams.JoinParams.Method {
case types.JoinMethodAzure, "":
matcher.InstallParams.JoinParams.Method = types.JoinMethodAzure
default:
return trace.BadParameter("only Azure joining is supported for Azure auto-discovery")
}
if token := matcher.InstallParams.JoinParams.TokenName; token == "" {
matcher.InstallParams.JoinParams.TokenName = defaults.AzureInviteTokenName
}
if installer := matcher.InstallParams.ScriptName; installer == "" {
matcher.InstallParams.ScriptName = installers.InstallerScriptName
}
return nil
}
// checkAndSetDefaultsForGCPMatchers sets the default values for GCP matchers
// and validates the provided types.
func checkAndSetDefaultsForGCPMatchers(matcherInput []GCPMatcher) error {
for i := range matcherInput {
matcher := &matcherInput[i]
if len(matcher.Types) == 0 {
return trace.BadParameter("At least one GCP discovery service type must be specified, the supported resource types are: %v",
services.SupportedGCPMatchers)
}
for _, matcherType := range matcher.Types {
if !slices.Contains(services.SupportedGCPMatchers, matcherType) {
return trace.BadParameter("GCP discovery service type does not support %q resource type; supported resource types are: %v",
matcherType, services.SupportedGCPMatchers)
}
}
if slices.Contains(matcher.Types, services.GCPMatcherCompute) {
if err := checkAndSetDefaultsForGCPInstaller(matcher); err != nil {
return trace.Wrap(err)
}
}
if slices.Contains(matcher.Locations, types.Wildcard) || len(matcher.Locations) == 0 {
matcher.Locations = []string{types.Wildcard}
}
if slices.Contains(matcher.ProjectIDs, types.Wildcard) {
return trace.BadParameter("GCP discovery service project_ids does not support wildcards; please specify at least one value in project_ids.")
}
if len(matcher.ProjectIDs) == 0 {
return trace.BadParameter("GCP discovery service project_ids does cannot be empty; please specify at least one value in project_ids.")
}
if len(matcher.Labels) > 0 && len(matcher.Tags) > 0 {
return trace.BadParameter("labels and tags should not both be set.")
}
if len(matcher.Tags) > 0 {
matcher.Labels = matcher.Tags
}
if len(matcher.Labels) == 0 {
matcher.Labels = map[string]apiutils.Strings{
types.Wildcard: {types.Wildcard},
}
}
}
return nil
}
func checkAndSetDefaultsForGCPInstaller(matcher *GCPMatcher) error {
if matcher.InstallParams == nil {
matcher.InstallParams = &InstallParams{
JoinParams: JoinParams{
TokenName: defaults.GCPInviteTokenName,
Method: types.JoinMethodGCP,
},
ScriptName: installers.InstallerScriptName,
}
return nil
}
switch matcher.InstallParams.JoinParams.Method {
case types.JoinMethodGCP, "":
matcher.InstallParams.JoinParams.Method = types.JoinMethodGCP
default:
return trace.BadParameter("only GCP joining is supported for GCP auto-discovery")
}
if token := matcher.InstallParams.JoinParams.TokenName; token == "" {
matcher.InstallParams.JoinParams.TokenName = defaults.GCPInviteTokenName
}
if installer := matcher.InstallParams.ScriptName; installer == "" {
matcher.InstallParams.ScriptName = installers.InstallerScriptName
}
return nil
}
// checkAndSetDefaultsForKubeMatchers sets the default values for Kubernetes matchers
// and validates the provided types.
func checkAndSetDefaultsForKubeMatchers(matchers []KubernetesMatcher) error {
for i := range matchers {
matcher := &matchers[i]
for _, t := range matcher.Types {
if !slices.Contains(services.SupportedKubernetesMatchers, t) {
return trace.BadParameter("Kubernetes discovery does not support %q resource type; supported resource types are: %v",
t, services.SupportedKubernetesMatchers)
}
}
if len(matcher.Types) == 0 {
matcher.Types = []string{services.KubernetesMatchersApp}
}
if len(matcher.Namespaces) == 0 {
matcher.Namespaces = []string{types.Wildcard}
}
if len(matcher.Labels) == 0 {
matcher.Labels = map[string]apiutils.Strings{types.Wildcard: {types.Wildcard}}
}
}
return nil
}
@ -1889,8 +1581,8 @@ type InstallParams struct {
Azure *AzureInstallParams `yaml:"azure,omitempty"`
}
func (ip *InstallParams) Parse() (types.InstallerParams, error) {
install := types.InstallerParams{
func (ip *InstallParams) parse() (*types.InstallerParams, error) {
install := &types.InstallerParams{
JoinMethod: ip.JoinParams.Method,
JoinToken: ip.JoinParams.TokenName,
ScriptName: ip.ScriptName,
@ -1905,7 +1597,7 @@ func (ip *InstallParams) Parse() (types.InstallerParams, error) {
var err error
install.InstallTeleport, err = apiutils.ParseBool(ip.InstallTeleport)
if err != nil {
return types.InstallerParams{}, trace.Wrap(err)
return nil, trace.Wrap(err)
}
return install, nil

View file

@ -33,7 +33,6 @@ import (
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/installers"
apiutils "github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/modules"
@ -866,581 +865,6 @@ func TestSSHSection(t *testing.T) {
}
}
func TestDiscoveryConfig(t *testing.T) {
t.Parallel()
testCases := []struct {
desc string
mutate func(cfgMap)
expectError require.ErrorAssertionFunc
expectEnabled require.BoolAssertionFunc
expectedDiscoverySection Discovery
}{
{
desc: "default",
mutate: func(cfgMap) {},
expectError: require.NoError,
expectEnabled: require.False,
expectedDiscoverySection: Discovery{},
},
{
desc: "GCP section without project_ids",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gke"},
},
}
},
expectedDiscoverySection: Discovery{},
},
{
desc: "GCP section is filled with defaults",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gke"},
"project_ids": []string{"p1", "p2"},
},
}
},
expectedDiscoverySection: Discovery{
GCPMatchers: []GCPMatcher{
{
Types: []string{"gke"},
Locations: []string{"*"},
Labels: map[string]apiutils.Strings{
"*": []string{"*"},
},
ProjectIDs: []string{"p1", "p2"},
},
},
},
},
{
desc: "GCP section is filled",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gke"},
"locations": []string{"eucentral1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"project_ids": []string{"p1", "p2"},
},
}
},
expectedDiscoverySection: Discovery{
GCPMatchers: []GCPMatcher{
{
Types: []string{"gke"},
Locations: []string{"eucentral1"},
Labels: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
ProjectIDs: []string{"p1", "p2"},
},
},
},
},
{
desc: "GCP section is filled with installer",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["gcp"] = []cfgMap{
{
"types": []string{"gce"},
"locations": []string{"eucentral1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"project_ids": []string{"p1", "p2"},
"service_accounts": []string{"a@example.com", "b@example.com"},
},
}
},
expectedDiscoverySection: Discovery{
GCPMatchers: []GCPMatcher{
{
Types: []string{"gke"},
Locations: []string{"eucentral1"},
Labels: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
ProjectIDs: []string{"p1", "p2"},
ServiceAccounts: []string{"a@example.com", "b@example.com"},
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: defaults.GCPInviteTokenName,
Method: types.JoinMethodGCP,
},
ScriptName: installers.InstallerScriptName,
},
},
},
},
},
{
desc: "Azure section is filled with defaults (aks)",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{
"types": []string{"aks"},
},
}
},
expectedDiscoverySection: Discovery{
AzureMatchers: []AzureMatcher{
{
Types: []string{"aks"},
Regions: []string{"*"},
ResourceTags: map[string]apiutils.Strings{
"*": []string{"*"},
},
Subscriptions: []string{"*"},
ResourceGroups: []string{"*"},
},
},
},
},
{
desc: "Azure section is filled with values",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{
"types": []string{"aks"},
"regions": []string{"eucentral1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"subscriptions": []string{"sub1", "sub2"},
"resource_groups": []string{"group1", "group2"},
},
}
},
expectedDiscoverySection: Discovery{
AzureMatchers: []AzureMatcher{
{
Types: []string{"aks"},
Regions: []string{"eucentral1"},
ResourceTags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
Subscriptions: []string{"sub1", "sub2"},
ResourceGroups: []string{"group1", "group2"},
},
},
},
},
{
desc: "AWS section is filled with defaults",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"ec2"},
"regions": []string{"eu-central-1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedDiscoverySection: Discovery{
AWSMatchers: []AWSMatcher{
{
Types: []string{"ec2"},
Regions: []string{"eu-central-1"},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: defaults.IAMInviteTokenName,
Method: types.JoinMethodIAM,
},
SSHDConfig: "/etc/ssh/sshd_config",
ScriptName: installers.InstallerScriptName,
},
SSM: AWSSSM{DocumentName: defaults.AWSInstallerDocument},
},
},
},
},
{
desc: "AWS section is filled with custom configs",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"ec2"},
"regions": []string{"eu-central-1"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"install": cfgMap{
"join_params": cfgMap{
"token_name": "hello-iam-a-token",
"method": "iam",
},
"script_name": "installer-custom",
},
"ssm": cfgMap{
"document_name": "hello_document",
},
"assume_role_arn": "arn:aws:iam::123456789012:role/DBDiscoverer",
"external_id": "externalID123",
},
}
},
expectedDiscoverySection: Discovery{
AWSMatchers: []AWSMatcher{
{
Types: []string{"ec2"},
Regions: []string{"eu-central-1"},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: "hello-iam-a-token",
Method: types.JoinMethodIAM,
},
SSHDConfig: "/etc/ssh/sshd_config",
ScriptName: "installer-custom",
},
SSM: AWSSSM{DocumentName: "hello_document"},
AssumeRoleARN: "arn:aws:iam::123456789012:role/DBDiscoverer",
ExternalID: "externalID123",
},
},
},
},
{
desc: "AWS section is filled with invalid region",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"ec2"},
"regions": []string{"*"},
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedDiscoverySection: Discovery{},
},
{
desc: "AWS section is filled with invalid join method",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"install": cfgMap{
"join_params": cfgMap{
"token_name": "hello-iam-a-token",
"method": "token",
},
},
},
}
},
expectedDiscoverySection: Discovery{},
},
{
desc: "AWS section is filled with external_id but empty assume_role_arn",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"rds"},
"regions": []string{"us-west-1"},
"assume_role_arn": "",
"external_id": "externalid123",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedDiscoverySection: Discovery{},
},
{
desc: "AWS section is filled with external_id but empty assume_role_arn is ok for redshift serverless",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"redshift-serverless"},
"regions": []string{"us-west-1"},
"assume_role_arn": "",
"external_id": "externalid123",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedDiscoverySection: Discovery{
AWSMatchers: []AWSMatcher{
{
Types: []string{"redshift-serverless"},
Regions: []string{"us-west-1"},
Tags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: "aws-discovery-iam-token",
Method: types.JoinMethodIAM,
},
SSHDConfig: "/etc/ssh/sshd_config",
ScriptName: "default-installer",
},
SSM: AWSSSM{DocumentName: "TeleportDiscoveryInstaller"},
AssumeRoleARN: "",
ExternalID: "externalid123",
},
},
},
},
{
desc: "AWS section is filled with invalid assume_role_arn",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"rds"},
"regions": []string{"us-west-1"},
"assume_role_arn": "foobar",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedDiscoverySection: Discovery{},
},
{
desc: "AWS section is filled with assume_role_arn that is not an iam ARN",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"types": []string{"rds"},
"regions": []string{"us-west-1"},
"assume_role_arn": "arn:aws:sts::123456789012:federated-user/Alice",
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedDiscoverySection: Discovery{},
},
{
desc: "AWS section is filled with no token",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["aws"] = []cfgMap{
{
"regions": []string{"eu-west-1"},
"install": cfgMap{
"join_params": cfgMap{
"method": "iam",
},
},
},
}
},
expectedDiscoverySection: Discovery{
AWSMatchers: []AWSMatcher{
{
SSM: AWSSSM{
DocumentName: defaults.AWSInstallerDocument,
},
Regions: []string{"eu-west-1"},
Tags: map[string]apiutils.Strings{"*": {"*"}},
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: defaults.IAMInviteTokenName,
Method: types.JoinMethodIAM,
},
ScriptName: installers.InstallerScriptName,
SSHDConfig: "/etc/ssh/sshd_config",
},
},
},
},
},
{
desc: "Azure section is filled with defaults (vm)",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{
"types": []string{"vm"},
"regions": []string{"westcentralus"},
"resource_groups": []string{"rg1"},
"subscriptions": []string{"88888888-8888-8888-8888-888888888888"},
"tags": cfgMap{
"discover_teleport": "yes",
},
},
}
},
expectedDiscoverySection: Discovery{
AzureMatchers: []AzureMatcher{
{
Types: []string{"vm"},
Regions: []string{"westcentralus"},
ResourceGroups: []string{"rg1"},
Subscriptions: []string{"88888888-8888-8888-8888-888888888888"},
ResourceTags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: "azure-discovery-token",
Method: "azure",
},
ScriptName: "default-installer",
},
},
},
},
},
{
desc: "Azure section is filled with custom config",
expectError: require.NoError,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{"types": []string{"vm"},
"regions": []string{"westcentralus"},
"resource_groups": []string{"rg1"},
"subscriptions": []string{"88888888-8888-8888-8888-888888888888"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"install": cfgMap{
"join_params": cfgMap{
"token_name": "custom-azure-token",
"method": "azure",
},
"script_name": "custom-installer",
"public_proxy_addr": "teleport.example.com",
},
},
}
},
expectedDiscoverySection: Discovery{
AzureMatchers: []AzureMatcher{
{
Types: []string{"vm"},
Regions: []string{"westcentralus"},
ResourceGroups: []string{"rg1"},
Subscriptions: []string{"88888888-8888-8888-8888-888888888888"},
ResourceTags: map[string]apiutils.Strings{
"discover_teleport": []string{"yes"},
},
InstallParams: &InstallParams{
JoinParams: JoinParams{
TokenName: "custom-azure-token",
Method: "azure",
},
ScriptName: "custom-installer",
PublicProxyAddr: "teleport.example.com",
},
},
},
},
},
{
desc: "Azure section is filled with invalid join method",
expectError: require.Error,
expectEnabled: require.True,
mutate: func(cfg cfgMap) {
cfg["discovery_service"].(cfgMap)["enabled"] = "yes"
cfg["discovery_service"].(cfgMap)["azure"] = []cfgMap{
{"types": []string{"vm"},
"regions": []string{"westcentralus"},
"resource_groups": []string{"rg1"},
"subscriptions": []string{"88888888-8888-8888-8888-888888888888"},
"tags": cfgMap{
"discover_teleport": "yes",
},
"install": cfgMap{
"join_params": cfgMap{
"token_name": "custom-azure-token",
"method": "token",
},
},
},
}
},
expectedDiscoverySection: Discovery{},
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
text := bytes.NewBuffer(editConfig(t, testCase.mutate))
cfg, err := ReadConfig(text)
testCase.expectError(t, err)
if cfg == nil {
return
}
testCase.expectEnabled(t, cfg.Discovery.Enabled())
if expectedAWS := testCase.expectedDiscoverySection.AWSMatchers; expectedAWS != nil {
require.Equal(t, expectedAWS, cfg.Discovery.AWSMatchers)
}
if expectedAzure := testCase.expectedDiscoverySection.AzureMatchers; expectedAzure != nil {
require.Equal(t, expectedAzure, cfg.Discovery.AzureMatchers)
}
})
}
}
func TestX11Config(t *testing.T) {
testCases := []struct {
desc string

View file

@ -174,7 +174,7 @@ var (
stsActions = []string{
"sts:AssumeRole",
}
// rdsActions contains IAM actions for services.AWSMatcherRDS (RDS
// rdsActions contains IAM actions for types.AWSMatcherRDS (RDS
// instances and Aurora clusters).
rdsActions = databaseActions{
discovery: []string{"rds:DescribeDBInstances", "rds:DescribeDBClusters"},
@ -183,7 +183,7 @@ var (
authBoundary: []string{"rds-db:connect"},
requireIAMEdit: true,
}
// rdsProxyActions contains IAM actions for services.AWSMatcherRDSProxy.
// rdsProxyActions contains IAM actions for types.AWSMatcherRDSProxy.
rdsProxyActions = databaseActions{
discovery: []string{
"rds:DescribeDBProxies",
@ -198,14 +198,14 @@ var (
authBoundary: []string{"rds-db:connect"},
requireIAMEdit: true,
}
// redshiftActions contains IAM actions for services.AWSMatcherRedshift.
// redshiftActions contains IAM actions for types.AWSMatcherRedshift.
redshiftActions = databaseActions{
discovery: []string{"redshift:DescribeClusters"},
metadata: []string{"redshift:DescribeClusters"},
authBoundary: []string{"redshift:GetClusterCredentials"},
requireIAMEdit: true,
}
// redshiftServerlessActions contains IAM actions for services.AWSMatcherRedshiftServerless.
// redshiftServerlessActions contains IAM actions for types.AWSMatcherRedshiftServerless.
redshiftServerlessActions = databaseActions{
discovery: []string{
"redshift-serverless:ListWorkgroups",
@ -218,7 +218,7 @@ var (
},
authBoundary: stsActions,
}
// elastiCacheActions contains IAM actions for services.AWSMatcherElastiCache.
// elastiCacheActions contains IAM actions for types.AWSMatcherElastiCache.
elastiCacheActions = databaseActions{
discovery: []string{
"elasticache:ListTagsForResource",
@ -237,7 +237,7 @@ var (
authBoundary: []string{"elasticache:Connect"},
requireIAMEdit: true,
}
// memoryDBActions contains IAM actions for services.AWSMatcherMemoryDB.
// memoryDBActions contains IAM actions for types.AWSMatcherMemoryDB.
memoryDBActions = databaseActions{
discovery: []string{
"memorydb:ListTags",
@ -261,7 +261,7 @@ var (
dynamodbActions = databaseActions{
authBoundary: stsActions,
}
// opensearchActions contains IAM actions for services.AWSMatcherOpenSearch
// opensearchActions contains IAM actions for types.AWSMatcherOpenSearch
opensearchActions = databaseActions{
discovery: []string{
"es:ListDomainNames",
@ -341,7 +341,7 @@ func (c *ConfiguratorConfig) CheckAndSetDefaults() error {
if c.AWSSSMClients == nil {
c.AWSSSMClients = make(map[string]ssmiface.SSMAPI)
for _, matcher := range c.ServiceConfig.Discovery.AWSMatchers {
if !slices.Contains(matcher.Types, services.AWSMatcherEC2) {
if !slices.Contains(matcher.Types, types.AWSMatcherEC2) {
continue
}
for _, region := range matcher.Regions {
@ -773,7 +773,7 @@ func getProxyAddrFromConfig(cfg *servicecfg.Config, flags configurators.Bootstra
func buildSSMDocumentCreators(ssm map[string]ssmiface.SSMAPI, targetCfg targetConfig, proxyAddr string) []configurators.ConfiguratorAction {
var creators []configurators.ConfiguratorAction
for _, matcher := range targetCfg.awsMatchers {
if !slices.Contains(matcher.Types, services.AWSMatcherEC2) {
if !slices.Contains(matcher.Types, types.AWSMatcherEC2) {
continue
}
for _, region := range matcher.Regions {
@ -792,7 +792,7 @@ func isEC2AutoDiscoveryEnabled(flags configurators.BootstrapFlags, matchers []ty
if flags.ForceEC2Permissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherEC2, matchers)
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherEC2, matchers)
}
// hasRDSDatabases checks if the agent needs permission for
@ -801,7 +801,7 @@ func hasRDSDatabases(flags configurators.BootstrapFlags, targetCfg targetConfig)
if flags.ForceRDSPermissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherRDS, targetCfg.awsMatchers) ||
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherRDS, targetCfg.awsMatchers) ||
findEndpointIs(targetCfg.databases, isRDSEndpoint)
}
@ -811,7 +811,7 @@ func hasRDSProxyDatabases(flags configurators.BootstrapFlags, targetCfg targetCo
if flags.ForceRDSProxyPermissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherRDSProxy, targetCfg.awsMatchers) ||
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherRDSProxy, targetCfg.awsMatchers) ||
findEndpointIs(targetCfg.databases, isRDSProxyEndpoint)
}
@ -821,7 +821,7 @@ func hasRedshiftDatabases(flags configurators.BootstrapFlags, targetCfg targetCo
if flags.ForceRedshiftPermissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherRedshift, targetCfg.awsMatchers) ||
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherRedshift, targetCfg.awsMatchers) ||
findEndpointIs(targetCfg.databases, apiawsutils.IsRedshiftEndpoint)
}
@ -831,7 +831,7 @@ func hasRedshiftServerlessDatabases(flags configurators.BootstrapFlags, targetCf
if flags.ForceRedshiftServerlessPermissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherRedshiftServerless, targetCfg.awsMatchers) ||
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherRedshiftServerless, targetCfg.awsMatchers) ||
findEndpointIs(targetCfg.databases, apiawsutils.IsRedshiftServerlessEndpoint)
}
@ -841,7 +841,7 @@ func hasElastiCacheDatabases(flags configurators.BootstrapFlags, targetCfg targe
if flags.ForceElastiCachePermissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherElastiCache, targetCfg.awsMatchers) ||
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherElastiCache, targetCfg.awsMatchers) ||
findEndpointIs(targetCfg.databases, apiawsutils.IsElastiCacheEndpoint)
}
@ -851,7 +851,7 @@ func hasMemoryDBDatabases(flags configurators.BootstrapFlags, targetCfg targetCo
if flags.ForceMemoryDBPermissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherMemoryDB, targetCfg.awsMatchers) ||
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherMemoryDB, targetCfg.awsMatchers) ||
findEndpointIs(targetCfg.databases, apiawsutils.IsMemoryDBEndpoint)
}
@ -861,7 +861,7 @@ func hasOpenSearchDatabases(flags configurators.BootstrapFlags, targetCfg target
if flags.ForceOpenSearchPermissions {
return true
}
return isAutoDiscoveryEnabledForMatcher(services.AWSMatcherOpenSearch, targetCfg.awsMatchers) ||
return isAutoDiscoveryEnabledForMatcher(types.AWSMatcherOpenSearch, targetCfg.awsMatchers) ||
findDatabaseIs(targetCfg.databases, func(db *servicecfg.Database) bool {
return db.Protocol == defaults.ProtocolOpenSearch
})
@ -942,7 +942,7 @@ func findAWSMatcherIs(matchers []types.AWSMatcher, is func(*types.AWSMatcher) bo
// AWS roles. Currently limited to just the AWS database matchers.
func supportsAWSAssumeRole(matcher types.AWSMatcher) bool {
for _, matcherType := range matcher.Types {
if slices.Contains(services.SupportedAWSDatabaseMatchers, matcherType) {
if slices.Contains(types.SupportedAWSDatabaseMatchers, matcherType) {
return true
}
}

View file

@ -80,7 +80,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
},
},
},
@ -110,7 +110,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
},
},
},
@ -174,7 +174,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
},
},
},
@ -201,7 +201,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
},
},
},
@ -259,7 +259,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}},
},
},
},
@ -410,7 +410,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherMemoryDB}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherMemoryDB}, Regions: []string{"us-west-2"}},
},
},
},
@ -545,7 +545,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{
Types: []string{services.AWSMatcherEC2},
Types: []string{types.AWSMatcherEC2},
Regions: []string{"eu-central-1"},
Tags: map[string]utils.Strings{"*": []string{"*"}},
InstallParams: &config.InstallParams{
@ -586,7 +586,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
},
},
},
@ -597,7 +597,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
},
},
},
@ -657,7 +657,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshiftServerless}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRedshiftServerless}, Regions: []string{"us-west-2"}},
},
},
},
@ -757,7 +757,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Databases: config.Databases{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherOpenSearch}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherOpenSearch}, Regions: []string{"us-west-2"}},
},
},
},
@ -831,8 +831,8 @@ func TestAWSIAMDocuments(t *testing.T) {
},
},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}, AssumeRoleARN: role4},
{Types: []string{services.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}, AssumeRoleARN: roleTarget.String(), ExternalID: "foo"},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}, AssumeRoleARN: role4},
{Types: []string{types.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}, AssumeRoleARN: roleTarget.String(), ExternalID: "foo"},
},
},
},
@ -880,8 +880,8 @@ func TestAWSIAMDocuments(t *testing.T) {
},
},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}, AssumeRoleARN: role4},
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}, AssumeRoleARN: role5, ExternalID: "foo"},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}, AssumeRoleARN: role4},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}, AssumeRoleARN: role5, ExternalID: "foo"},
},
},
},
@ -933,7 +933,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
},
},
},
@ -951,7 +951,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
},
},
},
@ -969,7 +969,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
},
},
},
@ -987,7 +987,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshiftServerless}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRedshiftServerless}, Regions: []string{"us-west-2"}},
},
},
},
@ -1005,7 +1005,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}},
},
},
},
@ -1023,7 +1023,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherMemoryDB}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherMemoryDB}, Regions: []string{"us-west-2"}},
},
},
},
@ -1041,7 +1041,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherOpenSearch}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherOpenSearch}, Regions: []string{"us-west-2"}},
},
},
},
@ -1059,9 +1059,9 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, Regions: []string{"us-west-1"}},
{Types: []string{services.AWSMatcherRedshift, services.AWSMatcherRDS, services.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
{Types: []string{services.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}, AssumeRoleARN: role1, ExternalID: "foo"},
{Types: []string{types.AWSMatcherRedshift}, Regions: []string{"us-west-1"}},
{Types: []string{types.AWSMatcherRedshift, types.AWSMatcherRDS, types.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}, AssumeRoleARN: role1, ExternalID: "foo"},
},
},
},
@ -1139,7 +1139,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDS}, Regions: []string{"us-west-2"}},
},
},
},
@ -1173,7 +1173,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
},
},
},
@ -1207,7 +1207,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRedshift}, Regions: []string{"us-west-2"}},
},
},
},
@ -1241,7 +1241,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshiftServerless}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherRedshiftServerless}, Regions: []string{"us-west-2"}},
},
},
},
@ -1265,7 +1265,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}},
},
},
},
@ -1319,7 +1319,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherMemoryDB}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherMemoryDB}, Regions: []string{"us-west-2"}},
},
},
},
@ -1363,7 +1363,7 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherOpenSearch}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherOpenSearch}, Regions: []string{"us-west-2"}},
},
},
},
@ -1387,9 +1387,9 @@ func TestAWSIAMDocuments(t *testing.T) {
Discovery: config.Discovery{
Service: config.Service{EnabledFlag: "true"},
AWSMatchers: []config.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, Regions: []string{"us-west-1"}},
{Types: []string{services.AWSMatcherRedshift, services.AWSMatcherRDS, services.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
{Types: []string{services.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}, AssumeRoleARN: role1, ExternalID: "foo"},
{Types: []string{types.AWSMatcherRedshift}, Regions: []string{"us-west-1"}},
{Types: []string{types.AWSMatcherRedshift, types.AWSMatcherRDS, types.AWSMatcherRDSProxy}, Regions: []string{"us-west-2"}},
{Types: []string{types.AWSMatcherElastiCache}, Regions: []string{"us-west-2"}, AssumeRoleARN: role1, ExternalID: "foo"},
},
},
},
@ -1922,7 +1922,7 @@ func TestExtractTargetConfig(t *testing.T) {
// check discovery resources are not included
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
Databases: servicecfg.DatabasesConfig{
@ -1933,11 +1933,11 @@ func TestExtractTargetConfig(t *testing.T) {
{Name: "db4", AWS: servicecfg.DatabaseAWS{AssumeRoleARN: roleTarget.String()}},
},
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role5, ExternalID: "foo"}},
{Types: []string{services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role6}},
{Types: []string{services.AWSMatcherElastiCache}},
{Types: []string{services.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role5, ExternalID: "foo"}},
{Types: []string{types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role6}},
{Types: []string{types.AWSMatcherElastiCache}},
{Types: []string{types.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
},
@ -1946,7 +1946,7 @@ func TestExtractTargetConfig(t *testing.T) {
assumesAWSRoles: []string{role1},
databases: []*servicecfg.Database{{Name: "db4", AWS: servicecfg.DatabaseAWS{AssumeRoleARN: roleTarget.String()}}},
awsMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
},
@ -1956,7 +1956,7 @@ func TestExtractTargetConfig(t *testing.T) {
cfg: &servicecfg.Config{
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
// check that database service resources are not included.
@ -1965,7 +1965,7 @@ func TestExtractTargetConfig(t *testing.T) {
{Name: "db1", AWS: servicecfg.DatabaseAWS{AssumeRoleARN: roleTarget.String()}},
},
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
},
@ -1973,7 +1973,7 @@ func TestExtractTargetConfig(t *testing.T) {
// identity field is ignored in want/got diff, see comment in test loop.
assumesAWSRoles: []string{role1},
awsMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
},
@ -1983,7 +1983,7 @@ func TestExtractTargetConfig(t *testing.T) {
cfg: &servicecfg.Config{
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
// check that database service resources are not included.
@ -1992,7 +1992,7 @@ func TestExtractTargetConfig(t *testing.T) {
{Name: "db1", AWS: servicecfg.DatabaseAWS{AssumeRoleARN: roleTarget.String()}},
},
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRedshift}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
},
@ -2000,7 +2000,7 @@ func TestExtractTargetConfig(t *testing.T) {
// identity field is ignored in want/got diff, see comment in test loop.
assumesAWSRoles: []string{role1},
awsMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
},
@ -2011,7 +2011,7 @@ func TestExtractTargetConfig(t *testing.T) {
// check that discovery service resources are not included.
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherEC2}},
{Types: []string{types.AWSMatcherEC2}},
},
},
Databases: servicecfg.DatabasesConfig{
@ -2022,12 +2022,12 @@ func TestExtractTargetConfig(t *testing.T) {
},
AWSMatchers: []types.AWSMatcher{
// rds/ec2 matcher's assume role should be added because rds assume role is supported.
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
// ec2-only matcher's assume role should not be added because it's not supported.
{Types: []string{services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role5}},
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role6, ExternalID: "foo"}},
{Types: []string{types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role5}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role6, ExternalID: "foo"}},
// matcher without assume role should be added to matchers
{Types: []string{services.AWSMatcherElastiCache}},
{Types: []string{types.AWSMatcherElastiCache}},
},
ResourceMatchers: []services.ResourceMatcher{
// dynamic resources' assume role should be added.
@ -2040,7 +2040,7 @@ func TestExtractTargetConfig(t *testing.T) {
assumesAWSRoles: []string{role1, role2, role3, role4, role6, role7},
databases: []*servicecfg.Database{{Name: "db3"}},
awsMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherElastiCache}},
{Types: []string{types.AWSMatcherElastiCache}},
},
},
},
@ -2050,9 +2050,9 @@ func TestExtractTargetConfig(t *testing.T) {
cfg: &servicecfg.Config{
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: role2}},
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: role3, ExternalID: "foo"}},
{Types: []string{services.AWSMatcherEC2}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: role2}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: role3, ExternalID: "foo"}},
{Types: []string{types.AWSMatcherEC2}},
},
},
// check that database service resources are not included.
@ -2061,7 +2061,7 @@ func TestExtractTargetConfig(t *testing.T) {
{Name: "db3"},
},
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherElastiCache}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
{Types: []string{types.AWSMatcherElastiCache}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
},
},
},
@ -2069,7 +2069,7 @@ func TestExtractTargetConfig(t *testing.T) {
// identity field is ignored in want/got diff, see comment in test loop.
assumesAWSRoles: []string{role1, role2, role3},
awsMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherEC2}},
{Types: []string{types.AWSMatcherEC2}},
},
},
},
@ -2079,7 +2079,7 @@ func TestExtractTargetConfig(t *testing.T) {
cfg: &servicecfg.Config{
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
Databases: servicecfg.DatabasesConfig{
@ -2087,15 +2087,15 @@ func TestExtractTargetConfig(t *testing.T) {
{Name: "db1", AWS: servicecfg.DatabaseAWS{AssumeRoleARN: role2}},
},
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDS}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
{Types: []string{services.AWSMatcherEC2}},
{Types: []string{types.AWSMatcherRDS}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
{Types: []string{types.AWSMatcherEC2}},
},
},
},
want: targetConfig{
// identity field is ignored in want/got diff, see comment in test loop.
awsMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherEC2}},
{Types: []string{types.AWSMatcherEC2}},
},
assumesAWSRoles: []string{role1, role2, role4},
},
@ -2106,7 +2106,7 @@ func TestExtractTargetConfig(t *testing.T) {
cfg: &servicecfg.Config{
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
Databases: servicecfg.DatabasesConfig{
@ -2114,7 +2114,7 @@ func TestExtractTargetConfig(t *testing.T) {
{Name: "db1", AWS: servicecfg.DatabaseAWS{AssumeRoleARN: role2}},
},
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role4}},
},
},
},
@ -2126,12 +2126,12 @@ func TestExtractTargetConfig(t *testing.T) {
cfg: &servicecfg.Config{
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
{Types: []string{types.AWSMatcherRDSProxy}, AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()}},
},
},
Databases: servicecfg.DatabasesConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role1}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}, AssumeRole: &types.AssumeRole{RoleARN: role1}},
},
},
},
@ -2146,19 +2146,19 @@ func TestExtractTargetConfig(t *testing.T) {
cfg: &servicecfg.Config{
Discovery: servicecfg.DiscoveryConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDSProxy}},
{Types: []string{types.AWSMatcherRDSProxy}},
},
},
Databases: servicecfg.DatabasesConfig{
AWSMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}},
},
},
},
want: targetConfig{
// identity field is ignored in want/got diff, see comment in test loop.
awsMatchers: []types.AWSMatcher{
{Types: []string{services.AWSMatcherRDS, services.AWSMatcherEC2}},
{Types: []string{types.AWSMatcherRDS, types.AWSMatcherEC2}},
},
},
},
@ -2204,7 +2204,7 @@ func TestIsTargetAssumeRole(t *testing.T) {
"target in matchers": {
target: roleTarget,
matchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-west-1"},
AssumeRole: &types.AssumeRole{RoleARN: roleTarget.String()},
}},
@ -2247,7 +2247,7 @@ func TestIsTargetAssumeRole(t *testing.T) {
target: roleTarget,
flags: configurators.BootstrapFlags{ForceAssumesRoles: role1},
matchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-west-1"},
AssumeRole: &types.AssumeRole{RoleARN: role1},
}},

View file

@ -890,35 +890,11 @@ func SearchSessionRange(clock clockwork.Clock, fromUTC, toUTC, recordingsSince s
}
const (
// AWSInstallerDocument is the name of the default AWS document
// that will be called when executing the SSM command.
AWSInstallerDocument = "TeleportDiscoveryInstaller"
// AWSAgentlessInstallerDocument is the name of the default AWS document
// that will be called when executing the SSM command .
AWSAgentlessInstallerDocument = "TeleportAgentlessDiscoveryInstaller"
// IAMInviteTokenName is the name of the default Teleport IAM
// token to use when templating the script to be executed.
IAMInviteTokenName = "aws-discovery-iam-token"
// SSHDConfigPath is the path to the sshd config file to modify
// when using the agentless installer
SSHDConfigPath = "/etc/ssh/sshd_config"
// HostnameLabel is the name of the label added to the sample SSH config generated by the teleport
// node configure command.
HostnameLabel = "hostname"
)
// AzureInviteTokenName is the name of the default token to use
// when templating the script to be executed on Azure.
const AzureInviteTokenName = "azure-discovery-token"
// GCPInviteTokenName is the name of the default token to use
// when templating the script to be executed on GCP.
const GCPInviteTokenName = "gcp-discovery-token"
const (
// FilePermissions are safe default permissions to use when
// creating files.

View file

@ -297,103 +297,3 @@ func (m *MatchResourceFilter) IsSimple() bool {
m.PredicateExpression == "" &&
len(m.Kinds) == 0
}
const (
// AWSMatcherEC2 is the AWS matcher type for EC2 instances.
AWSMatcherEC2 = "ec2"
// AWSMatcherEKS is the AWS matcher type for AWS Kubernetes.
AWSMatcherEKS = "eks"
// AWSMatcherRDS is the AWS matcher type for RDS databases.
AWSMatcherRDS = "rds"
// AWSMatcherRDSProxy is the AWS matcher type for RDS Proxy databases.
AWSMatcherRDSProxy = "rdsproxy"
// AWSMatcherRedshift is the AWS matcher type for Redshift databases.
AWSMatcherRedshift = "redshift"
// AWSMatcherRedshiftServerless is the AWS matcher type for Redshift Serverless databases.
AWSMatcherRedshiftServerless = "redshift-serverless"
// AWSMatcherElastiCache is the AWS matcher type for ElastiCache databases.
AWSMatcherElastiCache = "elasticache"
// AWSMatcherMemoryDB is the AWS matcher type for MemoryDB databases.
AWSMatcherMemoryDB = "memorydb"
// AWSMatcherOpenSearch is the AWS matcher type for OpenSearch databases.
AWSMatcherOpenSearch = "opensearch"
)
// SupportedAWSMatchers is list of AWS services currently supported by the
// Teleport discovery service.
var SupportedAWSMatchers = append([]string{
AWSMatcherEC2,
AWSMatcherEKS,
}, SupportedAWSDatabaseMatchers...)
// SupportedAWSDatabaseMatchers is a list of the AWS databases currently
// supported by the Teleport discovery service.
var SupportedAWSDatabaseMatchers = []string{
AWSMatcherRDS,
AWSMatcherRDSProxy,
AWSMatcherRedshift,
AWSMatcherRedshiftServerless,
AWSMatcherElastiCache,
AWSMatcherMemoryDB,
AWSMatcherOpenSearch,
}
// RequireAWSIAMRolesAsUsersMatchers is a list of the AWS databases that
// require AWS IAM roles as database users.
// IMPORTANT: if you add database matchers for AWS keyspaces, OpenSearch, or
// DynamoDB discovery, add them here and in RequireAWSIAMRolesAsUsers in
// api/types.
var RequireAWSIAMRolesAsUsersMatchers = []string{
AWSMatcherRedshiftServerless,
}
const (
// AzureMatcherVM is the Azure matcher type for Azure VMs.
AzureMatcherVM = "vm"
// AzureMatcherKubernetes is the Azure matcher type for Azure Kubernetes.
AzureMatcherKubernetes = "aks"
// AzureMatcherMySQL is the Azure matcher type for Azure MySQL databases.
AzureMatcherMySQL = "mysql"
// AzureMatcherPostgres is the Azure matcher type for Azure Postgres databases.
AzureMatcherPostgres = "postgres"
// AzureMatcherRedis is the Azure matcher type for Azure Cache for Redis databases.
AzureMatcherRedis = "redis"
// AzureMatcherSQLServer is the Azure matcher type for SQL Server databases.
AzureMatcherSQLServer = "sqlserver"
)
// SupportedAzureMatchers is list of Azure services currently supported by the
// Teleport discovery service.
var SupportedAzureMatchers = []string{
AzureMatcherVM,
AzureMatcherKubernetes,
AzureMatcherMySQL,
AzureMatcherPostgres,
AzureMatcherRedis,
AzureMatcherSQLServer,
}
const (
// GCPMatcherKubernetes is the GCP matcher type for GCP kubernetes.
GCPMatcherKubernetes = "gke"
// GCPMatcherCompute is the GCP matcher for GCP VMs.
GCPMatcherCompute = "gce"
)
// SupportedGCPMatchers is list of GCP services currently supported by the
// Teleport discovery service.
var SupportedGCPMatchers = []string{
GCPMatcherKubernetes,
GCPMatcherCompute,
}
const (
// KubernetesMatchersApp is app matcher type for Kubernetes services
KubernetesMatchersApp = "app"
)
// SupportedKubernetesMatchers is a list of Kubernetes matchers supported by
// Teleport discovery service
var SupportedKubernetesMatchers = []string{
KubernetesMatchersApp,
}

View file

@ -292,7 +292,7 @@ func TestWatcherCloudFetchers(t *testing.T) {
redshiftServerlessDatabase.SetStatusAWS(redshiftServerlessDatabase.GetAWS())
setDiscoveryGroupLabel(redshiftServerlessDatabase, "")
redshiftServerlessDatabase.SetOrigin(types.OriginCloud)
discovery.ApplyAWSDatabaseNameSuffix(redshiftServerlessDatabase, services.AWSMatcherRedshiftServerless)
discovery.ApplyAWSDatabaseNameSuffix(redshiftServerlessDatabase, types.AWSMatcherRedshiftServerless)
// Test an Azure fetcher.
azSQLServer, azSQLServerDatabase := makeAzureSQLServer(t, "discovery-azure", "group")
setDiscoveryGroupLabel(azSQLServerDatabase, "")
@ -318,11 +318,11 @@ func TestWatcherCloudFetchers(t *testing.T) {
},
AzureMatchers: []types.AzureMatcher{{
Subscriptions: []string{"sub"},
Types: []string{services.AzureMatcherSQLServer},
Types: []string{types.AzureMatcherSQLServer},
ResourceTags: types.Labels{types.Wildcard: []string{types.Wildcard}},
}},
AWSMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS, services.AWSMatcherRedshiftServerless},
Types: []string{types.AWSMatcherRDS, types.AWSMatcherRedshiftServerless},
Regions: []string{"us-east-1"},
Tags: types.Labels{types.Wildcard: []string{types.Wildcard}},
}},
@ -405,6 +405,6 @@ func makeAzureSQLServer(t *testing.T, name, group string) (*armsql.Server, types
}
database, err := services.NewDatabaseFromAzureSQLServer(server)
require.NoError(t, err)
discovery.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherSQLServer)
discovery.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherSQLServer)
return server, database
}

View file

@ -22,7 +22,6 @@ import (
"strings"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/services"
)
// ApplyAWSDatabaseNameSuffix applies the AWS Database Discovery name suffix to
@ -76,13 +75,13 @@ func ApplyAzureDatabaseNameSuffix(db types.Database, matcherType string) {
// By subtyping the matcher type, we can ensure these names do not collide.
func getDBMatcherSubtype(matcherType string, db types.Database) string {
switch matcherType {
case services.AWSMatcherRDS:
case types.AWSMatcherRDS:
if db.GetAWS().RDS.InstanceID == "" {
// distinguish RDS instances from clusters by subtyping the RDS
// matcher as "rds-aurora".
return "aurora"
}
case services.AzureMatcherRedis:
case types.AzureMatcherRedis:
if db.GetAzure().Redis.ClusteringPolicy != "" {
// distinguish Redis databases from Redis Enterprise database by
// subtyping the redis matcher as "redis-enterprise".
@ -103,7 +102,7 @@ func ApplyEKSNameSuffix(cluster types.KubeCluster) {
meta := cluster.GetAWSConfig()
suffix := makeAWSDiscoverySuffix(kubeClusterNamePartValidator,
cluster.GetName(),
services.AWSMatcherEKS,
types.AWSMatcherEKS,
"", // no EKS subtype
meta.Region,
meta.AccountID,
@ -123,7 +122,7 @@ func ApplyAKSNameSuffix(cluster types.KubeCluster) {
region, _ := cluster.GetLabel(types.DiscoveryLabelRegion)
suffix := makeAzureDiscoverySuffix(kubeClusterNamePartValidator,
cluster.GetName(),
services.AzureMatcherKubernetes,
types.AzureMatcherKubernetes,
"", // no AKS subtype
region,
meta.ResourceGroup,
@ -143,7 +142,7 @@ func ApplyGKENameSuffix(cluster types.KubeCluster) {
meta := cluster.GetGCPConfig()
suffix := makeGCPDiscoverySuffix(kubeClusterNamePartValidator,
cluster.GetName(),
services.GCPMatcherKubernetes,
types.GCPMatcherKubernetes,
"", // no GKE subtype
meta.Location,
meta.ProjectID,

View file

@ -191,7 +191,7 @@ func TestApplyAWSDatabaseNameSuffix(t *testing.T) {
resource: database,
renameFn: func(r types.ResourceWithLabels) {
db := r.(types.Database)
ApplyAWSDatabaseNameSuffix(db, services.AWSMatcherRDS)
ApplyAWSDatabaseNameSuffix(db, types.AWSMatcherRDS)
},
originalName: tt.dbName,
nameOverrideLabel: overrideLabel,
@ -220,7 +220,7 @@ func TestApplyAzureDatabaseNameSuffix(t *testing.T) {
region: "East US", // we normalize regions, so this should become "eastus".
resourceGroup: "Some Group",
subscriptionID: "11111111-2222-3333-4444-555555555555",
matcherType: services.AzureMatcherMySQL,
matcherType: types.AzureMatcherMySQL,
wantRename: "some-db-mysql-eastus-Some-Group-11111111-2222-3333-4444-555555555555",
makeDBFunc: makeAzureMySQLFlexDatabase,
},
@ -230,7 +230,7 @@ func TestApplyAzureDatabaseNameSuffix(t *testing.T) {
region: "eastus", // use the normalized region.
resourceGroup: "(parens are invalid)",
subscriptionID: "11111111-2222-3333-4444-555555555555",
matcherType: services.AzureMatcherMySQL,
matcherType: types.AzureMatcherMySQL,
wantRename: "some-db-mysql-eastus-11111111-2222-3333-4444-555555555555",
makeDBFunc: makeAzureMySQLFlexDatabase,
},
@ -240,7 +240,7 @@ func TestApplyAzureDatabaseNameSuffix(t *testing.T) {
region: "eastus",
resourceGroup: "Some Group",
subscriptionID: "11111111-2222-3333-4444-555555555555",
matcherType: services.AzureMatcherRedis,
matcherType: types.AzureMatcherRedis,
wantRename: "some-db-redis-eastus-Some-Group-11111111-2222-3333-4444-555555555555",
makeDBFunc: makeAzureRedisDB,
},
@ -250,7 +250,7 @@ func TestApplyAzureDatabaseNameSuffix(t *testing.T) {
region: "eastus",
resourceGroup: "Some Group",
subscriptionID: "11111111-2222-3333-4444-555555555555",
matcherType: services.AzureMatcherRedis,
matcherType: types.AzureMatcherRedis,
wantRename: "some-db-redis-enterprise-eastus-Some-Group-11111111-2222-3333-4444-555555555555",
makeDBFunc: makeAzureRedisEnterpriseDB,
},

View file

@ -254,7 +254,7 @@ func New(ctx context.Context, cfg *Config) (*Server, error) {
// initAWSWatchers starts AWS resource watchers based on types provided.
func (s *Server) initAWSWatchers(matchers []types.AWSMatcher) error {
ec2Matchers, otherMatchers := splitMatchers(matchers, func(matcherType string) bool {
return matcherType == services.AWSMatcherEC2
return matcherType == types.AWSMatcherEC2
})
// start ec2 watchers
@ -302,7 +302,7 @@ func (s *Server) initAWSWatchers(matchers []types.AWSMatcher) error {
for _, t := range matcher.Types {
for _, region := range matcher.Regions {
switch t {
case services.AWSMatcherEKS:
case types.AWSMatcherEKS:
client, err := s.CloudClients.GetAWSEKSClient(
s.ctx,
region,
@ -345,7 +345,7 @@ func (s *Server) initKubeAppWatchers(matchers []types.KubernetesMatcher) error {
}
for _, matcher := range matchers {
if !slices.Contains(matcher.Types, services.KubernetesMatchersApp) {
if !slices.Contains(matcher.Types, types.KubernetesMatchersApp) {
continue
}
@ -368,7 +368,7 @@ func (s *Server) initKubeAppWatchers(matchers []types.KubernetesMatcher) error {
// initAzureWatchers starts Azure resource watchers based on types provided.
func (s *Server) initAzureWatchers(ctx context.Context, matchers []types.AzureMatcher) error {
vmMatchers, otherMatchers := splitMatchers(matchers, func(matcherType string) bool {
return matcherType == services.AzureMatcherVM
return matcherType == types.AzureMatcherVM
})
// VM watcher.
@ -404,7 +404,7 @@ func (s *Server) initAzureWatchers(ctx context.Context, matchers []types.AzureMa
for _, subscription := range subscriptions {
for _, t := range matcher.Types {
switch t {
case services.AzureMatcherKubernetes:
case types.AzureMatcherKubernetes:
kubeClient, err := s.CloudClients.GetAzureKubernetesClient(subscription)
if err != nil {
return trace.Wrap(err)
@ -436,7 +436,7 @@ func (s *Server) initGCPWatchers(ctx context.Context, matchers []types.GCPMatche
}
vmMatchers, otherMatchers := splitMatchers(matchers, func(matcherType string) bool {
return matcherType == services.GCPMatcherCompute
return matcherType == types.GCPMatcherCompute
})
// VM watcher.
@ -462,7 +462,7 @@ func (s *Server) initGCPWatchers(ctx context.Context, matchers []types.GCPMatche
for _, location := range matcher.Locations {
for _, t := range matcher.Types {
switch t {
case services.GCPMatcherKubernetes:
case types.GCPMatcherKubernetes:
fetcher, err := fetchers.NewGKEFetcher(fetchers.GKEFetcherConfig{
Client: kubeClient,
Location: location,

View file

@ -1287,7 +1287,7 @@ func TestDiscoveryDatabase(t *testing.T) {
{
name: "discover AWS database",
awsMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRedshift},
Types: []string{types.AWSMatcherRedshift},
Tags: map[string]utils.Strings{types.Wildcard: {types.Wildcard}},
Regions: []string{"us-east-1"},
}},
@ -1297,7 +1297,7 @@ func TestDiscoveryDatabase(t *testing.T) {
{
name: "discover AWS database with assumed role",
awsMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Tags: map[string]utils.Strings{types.Wildcard: {types.Wildcard}},
Regions: []string{"us-west-1"},
AssumeRole: &role,
@ -1308,7 +1308,7 @@ func TestDiscoveryDatabase(t *testing.T) {
{
name: "discover Azure database",
azureMatchers: []types.AzureMatcher{{
Types: []string{services.AzureMatcherRedis},
Types: []string{types.AzureMatcherRedis},
ResourceTags: map[string]utils.Strings{types.Wildcard: {types.Wildcard}},
Regions: []string{types.Wildcard},
ResourceGroups: []string{types.Wildcard},
@ -1335,7 +1335,7 @@ func TestDiscoveryDatabase(t *testing.T) {
}),
},
awsMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRedshift},
Types: []string{types.AWSMatcherRedshift},
Tags: map[string]utils.Strings{types.Wildcard: {types.Wildcard}},
Regions: []string{"us-east-1"},
}},
@ -1354,7 +1354,7 @@ func TestDiscoveryDatabase(t *testing.T) {
}),
},
awsMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Tags: map[string]utils.Strings{types.Wildcard: {types.Wildcard}},
Regions: []string{"us-west-1"},
AssumeRole: &role,
@ -1374,7 +1374,7 @@ func TestDiscoveryDatabase(t *testing.T) {
}),
},
awsMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRedshift},
Types: []string{types.AWSMatcherRedshift},
Tags: map[string]utils.Strings{"do-not-match": {"do-not-match"}},
Regions: []string{"us-east-1"},
}},
@ -1402,7 +1402,7 @@ func TestDiscoveryDatabase(t *testing.T) {
}),
},
awsMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRedshift},
Types: []string{types.AWSMatcherRedshift},
Tags: map[string]utils.Strings{"do-not-match": {"do-not-match"}},
Regions: []string{"us-east-1"},
}},
@ -1521,7 +1521,7 @@ func makeRDSInstance(t *testing.T, name, region string, discoveryGroup string) (
staticLabels := database.GetStaticLabels()
staticLabels[types.TeleportInternalDiscoveryGroupName] = discoveryGroup
database.SetStaticLabels(staticLabels)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherRDS)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherRDS)
return instance, database
}
@ -1543,7 +1543,7 @@ func makeRedshiftCluster(t *testing.T, name, region string, discoveryGroup strin
staticLabels := database.GetStaticLabels()
staticLabels[types.TeleportInternalDiscoveryGroupName] = discoveryGroup
database.SetStaticLabels(staticLabels)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherRedshift)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherRedshift)
return cluster, database
}
@ -1566,7 +1566,7 @@ func makeAzureRedisServer(t *testing.T, name, subscription, group, region string
staticLabels := database.GetStaticLabels()
staticLabels[types.TeleportInternalDiscoveryGroupName] = discoveryGroup
database.SetStaticLabels(staticLabels)
common.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherRedis)
common.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherRedis)
return resourceInfo, database
}

View file

@ -57,7 +57,7 @@ func TestElastiCacheFetcher(t *testing.T) {
TagsByARN: elasticacheTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherElastiCache, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherElastiCache, "us-east-1", wildcardLabels),
wantDatabases: append(elasticacheDatabasesProd, elasticacheDatabasesQA...),
},
{
@ -68,7 +68,7 @@ func TestElastiCacheFetcher(t *testing.T) {
TagsByARN: elasticacheTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherElastiCache, "us-east-1", envProdLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherElastiCache, "us-east-1", envProdLabels),
wantDatabases: elasticacheDatabasesProd,
},
{
@ -79,7 +79,7 @@ func TestElastiCacheFetcher(t *testing.T) {
TagsByARN: elasticacheTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherElastiCache, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherElastiCache, "us-east-1", wildcardLabels),
wantDatabases: elasticacheDatabasesProd,
},
{
@ -90,7 +90,7 @@ func TestElastiCacheFetcher(t *testing.T) {
TagsByARN: elasticacheTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherElastiCache, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherElastiCache, "us-east-1", wildcardLabels),
wantDatabases: elasticacheDatabasesProd,
},
}
@ -109,14 +109,14 @@ func makeElastiCacheCluster(t *testing.T, name, region, env string, opts ...func
if aws.BoolValue(cluster.ClusterEnabled) {
database, err := services.NewDatabaseFromElastiCacheConfigurationEndpoint(cluster, extraLabels)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherElastiCache)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherElastiCache)
return cluster, types.Databases{database}, tags
}
databases, err := services.NewDatabasesFromElastiCacheNodeGroups(cluster, extraLabels)
require.NoError(t, err)
for _, database := range databases {
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherElastiCache)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherElastiCache)
}
return cluster, databases, tags
}

View file

@ -56,7 +56,7 @@ func TestMemoryDBFetcher(t *testing.T) {
TagsByARN: memorydbTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherMemoryDB, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherMemoryDB, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{memorydbDatabaseProd, memorydbDatabaseTest},
},
{
@ -67,7 +67,7 @@ func TestMemoryDBFetcher(t *testing.T) {
TagsByARN: memorydbTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherMemoryDB, "us-east-1", envProdLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherMemoryDB, "us-east-1", envProdLabels),
wantDatabases: types.Databases{memorydbDatabaseProd},
},
{
@ -78,7 +78,7 @@ func TestMemoryDBFetcher(t *testing.T) {
TagsByARN: memorydbTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherMemoryDB, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherMemoryDB, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{memorydbDatabaseProd},
},
{
@ -89,7 +89,7 @@ func TestMemoryDBFetcher(t *testing.T) {
TagsByARN: memorydbTagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherMemoryDB, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherMemoryDB, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{memorydbDatabaseProd},
},
}
@ -107,6 +107,6 @@ func makeMemoryDBCluster(t *testing.T, name, region, env string, opts ...func(*m
database, err := services.NewDatabaseFromMemoryDBCluster(cluster, extraLabels)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherMemoryDB)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherMemoryDB)
return cluster, database, tags
}

View file

@ -52,7 +52,7 @@ func TestOpenSearchFetcher(t *testing.T) {
TagsByARN: tags,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherOpenSearch, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherOpenSearch, "us-east-1", wildcardLabels),
wantDatabases: append(append(types.Databases{}, prodDBs...), testDBs...),
},
{
@ -63,7 +63,7 @@ func TestOpenSearchFetcher(t *testing.T) {
TagsByARN: tags,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherOpenSearch, "us-east-1", envProdLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherOpenSearch, "us-east-1", envProdLabels),
wantDatabases: prodDBs,
},
{
@ -74,7 +74,7 @@ func TestOpenSearchFetcher(t *testing.T) {
TagsByARN: tags,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherOpenSearch, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherOpenSearch, "us-east-1", wildcardLabels),
wantDatabases: prodDBs,
},
{
@ -85,7 +85,7 @@ func TestOpenSearchFetcher(t *testing.T) {
TagsByARN: tags,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherOpenSearch, "us-east-1", map[string]string{"endpoint-type": apiawsutils.OpenSearchDefaultEndpoint}),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherOpenSearch, "us-east-1", map[string]string{"endpoint-type": apiawsutils.OpenSearchDefaultEndpoint}),
wantDatabases: types.Databases{prodDBs[0], prodCustomDBs[0]}, // domain with custom endpoint will still have default endpoint populated
},
{
@ -96,7 +96,7 @@ func TestOpenSearchFetcher(t *testing.T) {
TagsByARN: tags,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherOpenSearch, "us-east-1", map[string]string{"endpoint-type": apiawsutils.OpenSearchCustomEndpoint}),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherOpenSearch, "us-east-1", map[string]string{"endpoint-type": apiawsutils.OpenSearchCustomEndpoint}),
wantDatabases: types.Databases{prodCustomDBs[1]}, // domain with custom endpoint will still have default endpoint populated
},
{
@ -107,7 +107,7 @@ func TestOpenSearchFetcher(t *testing.T) {
TagsByARN: tags,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherOpenSearch, "us-east-1", map[string]string{"endpoint-type": apiawsutils.OpenSearchVPCEndpoint}),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherOpenSearch, "us-east-1", map[string]string{"endpoint-type": apiawsutils.OpenSearchVPCEndpoint}),
wantDatabases: prodVPCDBs,
},
}
@ -128,7 +128,7 @@ func makeOpenSearchDomain(t *testing.T, tagMap map[string][]*opensearchservice.T
require.NoError(t, err)
for _, db := range databases {
common.ApplyAWSDatabaseNameSuffix(db, services.AWSMatcherOpenSearch)
common.ApplyAWSDatabaseNameSuffix(db, types.AWSMatcherOpenSearch)
}
return domain, databases
}

View file

@ -47,7 +47,7 @@ func TestRDSDBProxyFetcher(t *testing.T) {
DBProxyTargetPort: 9999,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRDSProxy, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRDSProxy, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{rdsProxyDatabaseVpc1, rdsProxyDatabaseVpc2, rdsProxyEndpointDatabaseVpc1, rdsProxyEndpointDatabaseVpc2},
},
{
@ -59,7 +59,7 @@ func TestRDSDBProxyFetcher(t *testing.T) {
DBProxyTargetPort: 9999,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRDSProxy, "us-east-1", map[string]string{"vpc-id": "vpc1"}),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRDSProxy, "us-east-1", map[string]string{"vpc-id": "vpc1"}),
wantDatabases: types.Databases{rdsProxyDatabaseVpc1, rdsProxyEndpointDatabaseVpc1},
},
}
@ -70,7 +70,7 @@ func makeRDSProxy(t *testing.T, name, region, vpcID string) (*rds.DBProxy, types
rdsProxy := mocks.RDSProxy(name, region, vpcID)
rdsProxyDatabase, err := services.NewDatabaseFromRDSProxy(rdsProxy, 9999, nil)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(rdsProxyDatabase, services.AWSMatcherRDSProxy)
common.ApplyAWSDatabaseNameSuffix(rdsProxyDatabase, types.AWSMatcherRDSProxy)
return rdsProxy, rdsProxyDatabase
}
@ -78,6 +78,6 @@ func makeRDSProxyCustomEndpoint(t *testing.T, rdsProxy *rds.DBProxy, name, regio
rdsProxyEndpoint := mocks.RDSProxyCustomEndpoint(rdsProxy, name, region)
rdsProxyEndpointDatabase, err := services.NewDatabaseFromRDSProxyCustomEndpoint(rdsProxy, rdsProxyEndpoint, 9999, nil)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(rdsProxyEndpointDatabase, services.AWSMatcherRDSProxy)
common.ApplyAWSDatabaseNameSuffix(rdsProxyEndpointDatabase, types.AWSMatcherRDSProxy)
return rdsProxyEndpoint, rdsProxyEndpointDatabase
}

View file

@ -72,12 +72,12 @@ func TestRDSFetchers(t *testing.T) {
},
inputMatchers: []types.AWSMatcher{
{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-1"},
Tags: toTypeLabels(wildcardLabels),
},
{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-2"},
Tags: toTypeLabels(wildcardLabels),
},
@ -105,12 +105,12 @@ func TestRDSFetchers(t *testing.T) {
},
inputMatchers: []types.AWSMatcher{
{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-1"},
Tags: toTypeLabels(envProdLabels),
},
{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-2"},
Tags: toTypeLabels(envDevLabels),
},
@ -138,12 +138,12 @@ func TestRDSFetchers(t *testing.T) {
},
inputMatchers: []types.AWSMatcher{
{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-1"},
Tags: toTypeLabels(wildcardLabels),
},
{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-2"},
Tags: toTypeLabels(wildcardLabels),
},
@ -161,7 +161,7 @@ func TestRDSFetchers(t *testing.T) {
},
},
inputMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-1"},
Tags: toTypeLabels(wildcardLabels),
}},
@ -177,7 +177,7 @@ func TestRDSFetchers(t *testing.T) {
},
},
inputMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-1"},
Tags: toTypeLabels(wildcardLabels),
}},
@ -192,7 +192,7 @@ func TestRDSFetchers(t *testing.T) {
},
},
inputMatchers: []types.AWSMatcher{{
Types: []string{services.AWSMatcherRDS},
Types: []string{types.AWSMatcherRDS},
Regions: []string{"us-east-1"},
Tags: toTypeLabels(wildcardLabels),
}},
@ -206,7 +206,7 @@ func makeRDSInstance(t *testing.T, name, region string, labels map[string]string
instance := mocks.RDSInstance(name, region, labels, opts...)
database, err := services.NewDatabaseFromRDSInstance(instance)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherRDS)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherRDS)
return instance, database
}
@ -214,7 +214,7 @@ func makeRDSCluster(t *testing.T, name, region string, labels map[string]string,
cluster := mocks.RDSCluster(name, region, labels, opts...)
database, err := services.NewDatabaseFromRDSCluster(cluster)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherRDS)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherRDS)
return cluster, database
}
@ -250,7 +250,7 @@ func makeRDSClusterWithExtraEndpoints(t *testing.T, name, region string, labels
databases = append(databases, customDatabases...)
for _, db := range databases {
common.ApplyAWSDatabaseNameSuffix(db, services.AWSMatcherRDS)
common.ApplyAWSDatabaseNameSuffix(db, types.AWSMatcherRDS)
}
return cluster, databases
}

View file

@ -58,7 +58,7 @@ func TestRedshiftServerlessFetcher(t *testing.T) {
TagsByARN: tagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRedshiftServerless, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRedshiftServerless, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{workgroupProdDB, workgroupDevDB, endpointProdDB, endpointProdDev},
},
{
@ -70,7 +70,7 @@ func TestRedshiftServerlessFetcher(t *testing.T) {
TagsByARN: tagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRedshiftServerless, "us-east-1", envProdLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRedshiftServerless, "us-east-1", envProdLabels),
wantDatabases: types.Databases{workgroupProdDB, endpointProdDB},
},
{
@ -82,7 +82,7 @@ func TestRedshiftServerlessFetcher(t *testing.T) {
TagsByARN: tagsByARN,
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRedshiftServerless, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRedshiftServerless, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{workgroupProdDB},
},
}
@ -94,7 +94,7 @@ func makeRedshiftServerlessWorkgroup(t *testing.T, name, region string, labels m
tags := libcloudaws.LabelsToTags[redshiftserverless.Tag](labels)
database, err := services.NewDatabaseFromRedshiftServerlessWorkgroup(workgroup, tags)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherRedshiftServerless)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherRedshiftServerless)
return workgroup, database
}
@ -103,6 +103,6 @@ func makeRedshiftServerlessEndpoint(t *testing.T, workgroup *redshiftserverless.
tags := libcloudaws.LabelsToTags[redshiftserverless.Tag](labels)
database, err := services.NewDatabaseFromRedshiftServerlessVPCEndpoint(endpoint, workgroup, tags)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherRedshiftServerless)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherRedshiftServerless)
return endpoint, database
}

View file

@ -46,7 +46,7 @@ func TestRedshiftFetcher(t *testing.T) {
Clusters: []*redshift.Cluster{redshiftUse1Prod, redshiftUse1Dev},
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRedshift, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRedshift, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{redshiftDatabaseUse1Prod, redshiftDatabaseUse1Dev},
},
{
@ -56,7 +56,7 @@ func TestRedshiftFetcher(t *testing.T) {
Clusters: []*redshift.Cluster{redshiftUse1Prod, redshiftUse1Dev},
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRedshift, "us-east-1", envProdLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRedshift, "us-east-1", envProdLabels),
wantDatabases: types.Databases{redshiftDatabaseUse1Prod},
},
{
@ -66,7 +66,7 @@ func TestRedshiftFetcher(t *testing.T) {
Clusters: []*redshift.Cluster{redshiftUse1Prod, redshiftUse1Unavailable, redshiftUse1UnknownStatus},
},
},
inputMatchers: makeAWSMatchersForType(services.AWSMatcherRedshift, "us-east-1", wildcardLabels),
inputMatchers: makeAWSMatchersForType(types.AWSMatcherRedshift, "us-east-1", wildcardLabels),
wantDatabases: types.Databases{redshiftDatabaseUse1Prod, redshiftDatabaseUnknownStatus},
},
}
@ -78,7 +78,7 @@ func makeRedshiftCluster(t *testing.T, region, env string, opts ...func(*redshif
database, err := services.NewDatabaseFromRedshiftCluster(cluster)
require.NoError(t, err)
common.ApplyAWSDatabaseNameSuffix(database, services.AWSMatcherRedshift)
common.ApplyAWSDatabaseNameSuffix(database, types.AWSMatcherRedshift)
return cluster, database
}

View file

@ -41,10 +41,10 @@ type azureDBServerPlugin struct{}
func (p *azureDBServerPlugin) GetListClient(cfg *azureFetcherConfig, subID string) (azure.DBServersClient, error) {
switch cfg.Type {
case services.AzureMatcherMySQL:
case types.AzureMatcherMySQL:
client, err := cfg.AzureClients.GetAzureMySQLClient(subID)
return client, trace.Wrap(err)
case services.AzureMatcherPostgres:
case types.AzureMatcherPostgres:
client, err := cfg.AzureClients.GetAzurePostgresClient(subID)
return client, trace.Wrap(err)
default:

View file

@ -83,7 +83,7 @@ func TestAzureDBServerFetchers(t *testing.T) {
{
Subscriptions: []string{subscription1},
ResourceGroups: []string{group1},
Types: []string{services.AzureMatcherMySQL, services.AzureMatcherPostgres},
Types: []string{types.AzureMatcherMySQL, types.AzureMatcherPostgres},
Regions: []string{eastus},
ResourceTags: types.Labels{"env": []string{"prod"}},
},
@ -121,7 +121,7 @@ func TestAzureDBServerFetchers(t *testing.T) {
{
Subscriptions: []string{"*"},
ResourceGroups: []string{"*"},
Types: []string{services.AzureMatcherMySQL, services.AzureMatcherPostgres},
Types: []string{types.AzureMatcherMySQL, types.AzureMatcherPostgres},
Regions: []string{"*"},
ResourceTags: types.Labels{"env": []string{"prod"}},
},
@ -161,7 +161,7 @@ func TestAzureDBServerFetchers(t *testing.T) {
{
Subscriptions: []string{subscription1},
ResourceGroups: []string{"*"},
Types: []string{services.AzureMatcherMySQL, services.AzureMatcherPostgres},
Types: []string{types.AzureMatcherMySQL, types.AzureMatcherPostgres},
Regions: []string{eastus},
ResourceTags: types.Labels{"*": []string{"*"}},
},
@ -195,7 +195,7 @@ func TestAzureDBServerFetchers(t *testing.T) {
{
Subscriptions: []string{subscription1},
ResourceGroups: []string{"*"},
Types: []string{services.AzureMatcherMySQL, services.AzureMatcherPostgres},
Types: []string{types.AzureMatcherMySQL, types.AzureMatcherPostgres},
Regions: []string{eastus},
ResourceTags: types.Labels{"*": []string{"*"}},
},
@ -230,7 +230,7 @@ func TestAzureDBServerFetchers(t *testing.T) {
{
Subscriptions: []string{subscription1, subscription2},
ResourceGroups: []string{"*"},
Types: []string{services.AzureMatcherMySQL, services.AzureMatcherPostgres},
Types: []string{types.AzureMatcherMySQL, types.AzureMatcherPostgres},
Regions: []string{eastus, westus},
ResourceTags: types.Labels{"*": []string{"*"}},
},
@ -269,7 +269,7 @@ func TestAzureDBServerFetchers(t *testing.T) {
{
Subscriptions: []string{subscription1},
ResourceGroups: []string{"foobar", group1, "baz"},
Types: []string{services.AzureMatcherMySQL, services.AzureMatcherPostgres},
Types: []string{types.AzureMatcherMySQL, types.AzureMatcherPostgres},
Regions: []string{eastus, westus},
ResourceTags: types.Labels{"*": []string{"*"}},
},
@ -346,7 +346,7 @@ func makeAzureMySQLServer(t *testing.T, name, subscription, group, region string
database, err := services.NewDatabaseFromAzureServer(azureDBServer)
require.NoError(t, err)
common.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherMySQL)
common.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherMySQL)
return server, database
}
@ -382,7 +382,7 @@ func makeAzurePostgresServer(t *testing.T, name, subscription, group, region str
database, err := services.NewDatabaseFromAzureServer(azureDBServer)
require.NoError(t, err)
common.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherPostgres)
common.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherPostgres)
return server, database
}

View file

@ -37,7 +37,7 @@ func TestAzureMySQLFlexFetchers(t *testing.T) {
azureSub := makeAzureSubscription(t, "sub123")
azMySQLFlexServer, azMySQLFlexDB := makeAzureMySQLFlexServer(t, "mysql-flex", "sub123", "group 1", "East US", map[string]string{"env": "prod"})
azureMatchers := []types.AzureMatcher{{
Types: []string{services.AzureMatcherMySQL},
Types: []string{types.AzureMatcherMySQL},
ResourceTags: types.Labels{"env": []string{"prod"}},
Regions: []string{"eastus"},
}}
@ -87,6 +87,6 @@ func makeAzureMySQLFlexServer(t *testing.T, name, subscription, group, region st
}
database, err := services.NewDatabaseFromAzureMySQLFlexServer(server)
require.NoError(t, err)
common.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherMySQL)
common.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherMySQL)
return server, database
}

View file

@ -37,7 +37,7 @@ func TestAzurePostgresFlexFetchers(t *testing.T) {
azureSub := makeAzureSubscription(t, "sub123")
azPostgresFlexServer, azPostgresFlexDB := makeAzurePostgresFlexServer(t, "postgres-flex", "sub123", "group 1", "East US", map[string]string{"env": "prod"})
azureMatchers := []types.AzureMatcher{{
Types: []string{services.AzureMatcherPostgres},
Types: []string{types.AzureMatcherPostgres},
ResourceTags: types.Labels{"env": []string{"prod"}},
Regions: []string{"eastus"},
}}
@ -87,6 +87,6 @@ func makeAzurePostgresFlexServer(t *testing.T, name, subscription, group, region
}
database, err := services.NewDatabaseFromAzurePostgresFlexServer(server)
require.NoError(t, err)
common.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherPostgres)
common.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherPostgres)
return server, database
}

View file

@ -47,7 +47,7 @@ func TestAzureRedisFetchers(t *testing.T) {
azRedisEnterpriseCluster, azRedisEnterpriseDatabase, azRedisEnterpriseDB := makeAzureRedisEnterpriseCluster(t, "redis-enterprise", "sub", "group", "eastus", map[string]string{"env": "prod"})
azureMatchers := []types.AzureMatcher{{
Types: []string{services.AzureMatcherRedis},
Types: []string{types.AzureMatcherRedis},
ResourceTags: types.Labels{"env": []string{"prod"}},
Regions: []string{"eastus"},
}}
@ -88,7 +88,7 @@ func makeAzureRedisServer(t *testing.T, name, subscription, group, region string
database, err := services.NewDatabaseFromAzureRedis(resourceInfo)
require.NoError(t, err)
common.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherRedis)
common.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherRedis)
return resourceInfo, database
}
@ -115,6 +115,6 @@ func makeAzureRedisEnterpriseCluster(t *testing.T, cluster, subscription, group,
database, err := services.NewDatabaseFromAzureRedisEnterprise(armCluster, armDatabase)
require.NoError(t, err)
common.ApplyAzureDatabaseNameSuffix(database, services.AzureMatcherRedis)
common.ApplyAzureDatabaseNameSuffix(database, types.AzureMatcherRedis)
return armCluster, armDatabase, database
}

View file

@ -34,20 +34,20 @@ type makeAzureFetcherFunc func(azureFetcherConfig) (common.Fetcher, error)
var (
makeAWSFetcherFuncs = map[string][]makeAWSFetcherFunc{
services.AWSMatcherRDS: {newRDSDBInstancesFetcher, newRDSAuroraClustersFetcher},
services.AWSMatcherRDSProxy: {newRDSDBProxyFetcher},
services.AWSMatcherRedshift: {newRedshiftFetcher},
services.AWSMatcherRedshiftServerless: {newRedshiftServerlessFetcher},
services.AWSMatcherElastiCache: {newElastiCacheFetcher},
services.AWSMatcherMemoryDB: {newMemoryDBFetcher},
services.AWSMatcherOpenSearch: {newOpenSearchFetcher},
types.AWSMatcherRDS: {newRDSDBInstancesFetcher, newRDSAuroraClustersFetcher},
types.AWSMatcherRDSProxy: {newRDSDBProxyFetcher},
types.AWSMatcherRedshift: {newRedshiftFetcher},
types.AWSMatcherRedshiftServerless: {newRedshiftServerlessFetcher},
types.AWSMatcherElastiCache: {newElastiCacheFetcher},
types.AWSMatcherMemoryDB: {newMemoryDBFetcher},
types.AWSMatcherOpenSearch: {newOpenSearchFetcher},
}
makeAzureFetcherFuncs = map[string][]makeAzureFetcherFunc{
services.AzureMatcherMySQL: {newAzureMySQLFetcher, newAzureMySQLFlexServerFetcher},
services.AzureMatcherPostgres: {newAzurePostgresFetcher, newAzurePostgresFlexServerFetcher},
services.AzureMatcherRedis: {newAzureRedisFetcher, newAzureRedisEnterpriseFetcher},
services.AzureMatcherSQLServer: {newAzureSQLServerFetcher, newAzureManagedSQLServerFetcher},
types.AzureMatcherMySQL: {newAzureMySQLFetcher, newAzureMySQLFlexServerFetcher},
types.AzureMatcherPostgres: {newAzurePostgresFetcher, newAzurePostgresFlexServerFetcher},
types.AzureMatcherRedis: {newAzureRedisFetcher, newAzureRedisEnterpriseFetcher},
types.AzureMatcherSQLServer: {newAzureSQLServerFetcher, newAzureManagedSQLServerFetcher},
}
)

View file

@ -166,7 +166,7 @@ func (f *KubeAppFetcher) Get(ctx context.Context) (types.ResourcesWithLabels, er
service := service
// Skip service if it has type annotation and it's not 'app'
if v, ok := service.GetAnnotations()[types.DiscoveryTypeLabel]; ok && v != services.KubernetesMatchersApp {
if v, ok := service.GetAnnotations()[types.DiscoveryTypeLabel]; ok && v != types.KubernetesMatchersApp {
continue
}

View file

@ -31,7 +31,6 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/cloud"
awslib "github.com/gravitational/teleport/lib/cloud/aws"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/labels"
)
@ -131,7 +130,7 @@ func WithPollInterval(interval time.Duration) Option {
// MakeEvents generates ResourceCreateEvents for these instances.
func (instances *EC2Instances) MakeEvents() map[string]*usageeventsv1.ResourceCreateEvent {
resourceType := types.DiscoveredResourceNode
if instances.DocumentName == defaults.AWSAgentlessInstallerDocument {
if instances.DocumentName == types.AWSAgentlessInstallerDocument {
resourceType = types.DiscoveredResourceAgentlessNode
}
events := make(map[string]*usageeventsv1.ResourceCreateEvent, len(instances.Instances))

View file

@ -370,13 +370,13 @@ func BuildRoleARN(username, region, accountID string) (string, error) {
if !IsPartialRoleARN(resource) {
resource = fmt.Sprintf("role/%s", username)
}
roleARN := &arn.ARN{
roleARN := arn.ARN{
Partition: partition,
Service: iam.ServiceName,
AccountID: accountID,
Resource: resource,
}
if err := checkRoleARN(roleARN); err != nil {
if err := apiawsutils.CheckRoleARN(roleARN.String()); err != nil {
return "", trace.Wrap(err)
}
return roleARN.String(), nil