mirror of
https://github.com/gravitational/teleport
synced 2024-10-19 08:43:58 +00:00
DiscoveryMatchers: move checkandset to types package (#32857)
* DiscoveryMatchers: move checkandset to types package * add opensearch to iamrole as users
This commit is contained in:
parent
41edd25cb5
commit
44209ce8dc
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
243
api/types/matchers_aws_test.go
Normal file
243
api/types/matchers_aws_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
129
api/types/matchers_azure_test.go
Normal file
129
api/types/matchers_azure_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
160
api/types/matchers_gcp_test.go
Normal file
160
api/types/matchers_gcp_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
88
api/types/matchers_kube_test.go
Normal file
88
api/types/matchers_kube_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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},
|
||||
}},
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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},
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue