Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UserTasks: Add SSM Document and Installer for DiscoverEC2 Issues #47626

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 57 additions & 32 deletions api/gen/proto/go/teleport/usertasks/v1/user_tasks.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions api/proto/teleport/usertasks/v1/user_tasks.proto
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ message DiscoverEC2 {
string account_id = 2;
// Region is the AWS Region where Teleport failed to enroll EC2 instances.
string region = 3;
// SSMDocument is the Amazon Systems Manager SSM Document name that was used to install teleport on the instance.
// In Amazon console, the document is at:
// https://REGION.console.aws.amazon.com/systems-manager/documents/SSM_DOCUMENT/description
string ssm_document = 4;
// InstallerScript is the Teleport installer script that was used to install teleport on the instance.
string installer_script = 5;
}

// DiscoverEC2Instance contains the result of enrolling an AWS EC2 Instance.
Expand Down
14 changes: 10 additions & 4 deletions api/types/usertasks/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,12 @@ func validateDiscoverEC2TaskType(ut *usertasksv1.UserTask) error {
// TaskNameForDiscoverEC2Parts are the fields that deterministically compute a Discover EC2 task name.
// To be used with TaskNameForDiscoverEC2 function.
type TaskNameForDiscoverEC2Parts struct {
Integration string
IssueType string
AccountID string
Region string
Integration string
IssueType string
AccountID string
Region string
SSMDocument string
InstallerScript string
}

// TaskNameForDiscoverEC2 returns a deterministic name for the DiscoverEC2 task type.
Expand All @@ -233,6 +235,10 @@ func TaskNameForDiscoverEC2(parts TaskNameForDiscoverEC2Parts) string {
bs = append(bs, []byte(parts.AccountID)...)
bs = append(bs, binary.LittleEndian.AppendUint64(nil, uint64(len(parts.Region)))...)
bs = append(bs, []byte(parts.Region)...)
bs = append(bs, binary.LittleEndian.AppendUint64(nil, uint64(len(parts.SSMDocument)))...)
bs = append(bs, []byte(parts.SSMDocument)...)
bs = append(bs, binary.LittleEndian.AppendUint64(nil, uint64(len(parts.InstallerScript)))...)
bs = append(bs, []byte(parts.InstallerScript)...)
return uuid.NewSHA1(discoverEC2Namespace, bs).String()
}

Expand Down
2 changes: 1 addition & 1 deletion api/types/usertasks/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func TestNewDiscoverEC2UserTask(t *testing.T) {
Kind: "user_task",
Version: "v1",
Metadata: &headerv1.Metadata{
Name: "154e1429-da26-5ce2-add2-b0e77a27dd96",
Name: "f36b8798-fdec-59fe-8bd0-33f4890ced05",
Expires: userTaskExpirationTimestamp,
},
Spec: baseEC2DiscoverTaskSpec,
Expand Down
10 changes: 6 additions & 4 deletions lib/srv/discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -981,10 +981,12 @@ func (s *Server) handleEC2RemoteInstallation(instances *server.EC2Instances) err
for _, instance := range req.Instances {
s.awsEC2Tasks.addFailedEnrollment(
awsEC2TaskKey{
accountID: instances.AccountID,
integration: instances.Integration,
issueType: usertasks.AutoDiscoverEC2IssueSSMInvocationFailure,
region: instances.Region,
accountID: instances.AccountID,
integration: instances.Integration,
issueType: usertasks.AutoDiscoverEC2IssueSSMInvocationFailure,
region: instances.Region,
ssmDocument: req.DocumentName,
installerScript: req.InstallerScriptName(),
},
&usertasksv1.DiscoverEC2Instance{
// TODO(marco): add instance name
Expand Down
30 changes: 18 additions & 12 deletions lib/srv/discovery/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,12 @@ func (s *Server) ReportEC2SSMInstallationResult(ctx context.Context, result *ser

s.awsEC2Tasks.addFailedEnrollment(
awsEC2TaskKey{
integration: result.IntegrationName,
issueType: result.IssueType,
accountID: result.SSMRunEvent.AccountID,
region: result.SSMRunEvent.Region,
integration: result.IntegrationName,
issueType: result.IssueType,
accountID: result.SSMRunEvent.AccountID,
region: result.SSMRunEvent.Region,
ssmDocument: result.SSMDocumentName,
installerScript: result.InstallerScript,
},
&usertasksv1.DiscoverEC2Instance{
// TODO(marco): add instance name
Expand Down Expand Up @@ -333,10 +335,12 @@ type awsEC2Tasks struct {

// awsEC2TaskKey identifies a UserTask group.
type awsEC2TaskKey struct {
integration string
issueType string
accountID string
region string
integration string
issueType string
accountID string
region string
ssmDocument string
installerScript string
}

// iterationStarted clears out any in memory issues that were recorded.
Expand Down Expand Up @@ -431,10 +435,12 @@ func (s *Server) acquireSemaphoreForUserTask(userTaskName string) (releaseFn fun
// All of this flow is protected by a lock to ensure there's no race between this and other DiscoveryServices.
func (s *Server) mergeUpsertDiscoverEC2Task(taskGroup awsEC2TaskKey, failedInstances map[string]*usertasksv1.DiscoverEC2Instance) error {
userTaskName := usertasks.TaskNameForDiscoverEC2(usertasks.TaskNameForDiscoverEC2Parts{
Integration: taskGroup.integration,
IssueType: taskGroup.issueType,
AccountID: taskGroup.accountID,
Region: taskGroup.region,
Integration: taskGroup.integration,
IssueType: taskGroup.issueType,
AccountID: taskGroup.accountID,
Region: taskGroup.region,
SSMDocument: taskGroup.ssmDocument,
InstallerScript: taskGroup.installerScript,
})

releaseFn, ctxWithLease, err := s.acquireSemaphoreForUserTask(userTaskName)
Expand Down
20 changes: 20 additions & 0 deletions lib/srv/server/ssm_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ type SSMInstallationResult struct {
// IssueType identifies the type of issue that occurred if the installation failed.
// These are well known identifiers that can be found at types.AutoDiscoverEC2Issue*.
IssueType string
// SSMDocumentName is the Amazon SSM Document Name used to install Teleport into the instance.
SSMDocumentName string
// InstallerScript is the Teleport Installer script name used to install Teleport into the instance.
InstallerScript string
}

// SSMInstaller handles running SSM commands that install Teleport on EC2 instances.
Expand Down Expand Up @@ -95,6 +99,16 @@ type SSMRunRequest struct {
DiscoveryConfig string
}

// InstallerScriptName returns the Teleport Installer script name.
// Returns empty string if not defined.
func (r *SSMRunRequest) InstallerScriptName() string {
if r == nil || r.Params == nil {
return ""
}

return r.Params[ParamScriptName]
}

// CheckAndSetDefaults ensures the emitter is present and creates a default logger if one is not provided.
func (c *SSMInstallerConfig) checkAndSetDefaults() error {
if c.ReportSSMInstallationResultFunc == nil {
Expand Down Expand Up @@ -212,6 +226,8 @@ func invalidSSMInstanceInstallationResult(req SSMRunRequest, instanceID, status,
IntegrationName: req.IntegrationName,
DiscoveryConfig: req.DiscoveryConfig,
IssueType: issueType,
SSMDocumentName: req.DocumentName,
InstallerScript: req.InstallerScriptName(),
}
}

Expand Down Expand Up @@ -359,6 +375,8 @@ func (si *SSMInstaller) checkCommand(ctx context.Context, req SSMRunRequest, com
IntegrationName: req.IntegrationName,
DiscoveryConfig: req.DiscoveryConfig,
IssueType: usertasks.AutoDiscoverEC2IssueSSMScriptFailure,
SSMDocumentName: req.DocumentName,
InstallerScript: req.InstallerScriptName(),
}))
}

Expand All @@ -373,6 +391,8 @@ func (si *SSMInstaller) checkCommand(ctx context.Context, req SSMRunRequest, com
IntegrationName: req.IntegrationName,
DiscoveryConfig: req.DiscoveryConfig,
IssueType: usertasks.AutoDiscoverEC2IssueSSMScriptFailure,
SSMDocumentName: req.DocumentName,
InstallerScript: req.InstallerScriptName(),
}))
}
}
Expand Down
Loading
Loading