Skip to content

Commit

Permalink
UserTasks: Add SSM Document and Installer for DiscoverEC2 Issues
Browse files Browse the repository at this point in the history
This PR adds two new fields to the DiscoverEC2 User Task.
SSM Document used to install teleport
Teleport Installer script name used to install teleport

This can be used to let the user know which scripts were used.
For the SSM Document, users can then open it in webui.
For the Installer Script, users can manage it using `tctl` client.
  • Loading branch information
marcoandredinis committed Oct 16, 2024
1 parent d602f89 commit 9466c67
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 20 deletions.
45 changes: 35 additions & 10 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 @@ -89,4 +89,10 @@ message DiscoverEC2Instance {
string discovery_group = 7;
// SyncTime is the timestamp when the error was produced.
google.protobuf.Timestamp sync_time = 8;
// 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 = 9;
// InstallerScript is the Teleport installer script that was used to install teleport on the instance.
string installer_script = 10;
}
2 changes: 2 additions & 0 deletions lib/srv/discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,8 @@ func (s *Server) handleEC2RemoteInstallation(instances *server.EC2Instances) err
DiscoveryGroup: s.DiscoveryGroup,
InstanceId: instance.InstanceID,
SyncTime: timestamppb.New(s.clock.Now()),
SsmDocument: req.DocumentName,
InstallerScript: req.InstallerScriptName(),
},
)
}
Expand Down
2 changes: 2 additions & 0 deletions lib/srv/discovery/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ func (s *Server) ReportEC2SSMInstallationResult(ctx context.Context, result *ser
DiscoveryGroup: s.DiscoveryGroup,
SyncTime: timestamppb.New(result.SSMRunEvent.Time),
InstanceId: result.SSMRunEvent.InstanceID,
SsmDocument: result.SSMDocumentName,
InstallerScript: result.InstallerScript,
},
)

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
30 changes: 20 additions & 10 deletions lib/srv/server/ssm_install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ func TestSSMInstaller(t *testing.T) {
Status: ssm.CommandStatusSuccess,
InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1",
},
IssueType: "ec2-ssm-script-failure",
IssueType: "ec2-ssm-script-failure",
SSMDocumentName: "ssmdocument",
}},
},
{
Expand Down Expand Up @@ -189,7 +190,8 @@ func TestSSMInstaller(t *testing.T) {
Status: ssm.CommandStatusSuccess,
InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1",
},
IssueType: "ec2-ssm-script-failure",
IssueType: "ec2-ssm-script-failure",
SSMDocumentName: "ssmdocument-without-sshdConfigPath-param",
}},
},
{
Expand Down Expand Up @@ -236,7 +238,8 @@ func TestSSMInstaller(t *testing.T) {
StandardError: "timeout error",
InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1",
},
IssueType: "ec2-ssm-script-failure",
IssueType: "ec2-ssm-script-failure",
SSMDocumentName: "ssmdocument",
}},
},
{
Expand Down Expand Up @@ -287,7 +290,8 @@ func TestSSMInstaller(t *testing.T) {
StandardError: "timeout error",
InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1",
},
IssueType: "ec2-ssm-script-failure",
IssueType: "ec2-ssm-script-failure",
SSMDocumentName: "ssmdocument",
}},
},
{
Expand Down Expand Up @@ -355,7 +359,8 @@ func TestSSMInstaller(t *testing.T) {
Status: ssm.CommandStatusSuccess,
InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1",
},
IssueType: "ec2-ssm-script-failure",
IssueType: "ec2-ssm-script-failure",
SSMDocumentName: "ssmdocument",
},
{
SSMRunEvent: &events.SSMRun{
Expand All @@ -370,7 +375,8 @@ func TestSSMInstaller(t *testing.T) {
ExitCode: -1,
Status: "SSM Agent in EC2 Instance is not connecting to SSM Service. Restart or reinstall the SSM service. See https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html#verify-ssm-agent-status for more details.",
},
IssueType: "ec2-ssm-agent-connection-lost",
IssueType: "ec2-ssm-agent-connection-lost",
SSMDocumentName: "ssmdocument",
},
{
SSMRunEvent: &events.SSMRun{
Expand All @@ -385,7 +391,8 @@ func TestSSMInstaller(t *testing.T) {
ExitCode: -1,
Status: "EC2 instance is running an unsupported Operating System. Only Linux is supported.",
},
IssueType: "ec2-ssm-unsupported-os",
IssueType: "ec2-ssm-unsupported-os",
SSMDocumentName: "ssmdocument",
},
{
SSMRunEvent: &events.SSMRun{
Expand All @@ -400,7 +407,8 @@ func TestSSMInstaller(t *testing.T) {
ExitCode: -1,
Status: "EC2 Instance is not registered in SSM. Make sure that the instance has AmazonSSMManagedInstanceCore policy assigned.",
},
IssueType: "ec2-ssm-agent-not-registered",
IssueType: "ec2-ssm-agent-not-registered",
SSMDocumentName: "ssmdocument",
},
},
},
Expand Down Expand Up @@ -456,7 +464,8 @@ func TestSSMInstaller(t *testing.T) {
StandardOutput: "custom output",
InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1",
},
IssueType: "ec2-ssm-script-failure",
IssueType: "ec2-ssm-script-failure",
SSMDocumentName: "ssmdocument",
}},
},
{
Expand Down Expand Up @@ -497,7 +506,8 @@ func TestSSMInstaller(t *testing.T) {
Status: ssm.CommandStatusSuccess,
InvocationURL: "https://eu-central-1.console.aws.amazon.com/systems-manager/run-command/command-id-1/instance-id-1",
},
IssueType: "ec2-ssm-script-failure",
IssueType: "ec2-ssm-script-failure",
SSMDocumentName: "ssmdocument",
}},
},
// todo(amk): test that incomplete commands eventually return
Expand Down

0 comments on commit 9466c67

Please sign in to comment.