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 title per issue type #52435

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
33 changes: 24 additions & 9 deletions lib/usertasks/descriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,52 @@ package usertasks
import (
"embed"
"fmt"
"strings"
)

//go:embed descriptions/*.md
var descriptionsFS embed.FS

func loadIssueDescription(issueType string) string {
func loadIssueTitleDescription(issueType string) (string, string) {
filename := fmt.Sprintf("descriptions/%s.md", issueType)
bs, err := descriptionsFS.ReadFile(filename)
if err != nil {
return ""
return "", ""
}
return string(bs)

documentParts := strings.SplitN(string(bs), "\n", 2)
if len(documentParts) != 2 {
return "", ""
}

title := documentParts[0]
if !strings.HasPrefix(title, "# ") {
return "", ""
}
title = title[2:]

description := strings.TrimSpace(documentParts[1])
Comment on lines +42 to +48
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the title does not start with an "#", is it better to return nothing, or an empty title and shove the whole bs string into the description?

I'm worried that someone will make a typo/forget the # and this would lead to obscure user tasks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a test that iterates over all IssueTypes and ensures none of them returns an empty string for both title and description.
That should be enough to prevent such scenario


return title, description
}

// DescriptionForDiscoverEC2Issue returns the description of the issue and fixing steps.
// The returned string contains a markdown document.
// If issue type is not recognized or doesn't have a specific description, them an empty string is returned.
func DescriptionForDiscoverEC2Issue(issueType string) string {
return loadIssueDescription(issueType)
func DescriptionForDiscoverEC2Issue(issueType string) (string, string) {
return loadIssueTitleDescription(issueType)
}

// DescriptionForDiscoverEKSIssue returns the description of the issue and fixing steps.
// The returned string contains a markdown document.
// If issue type is not recognized or doesn't have a specific description, them an empty string is returned.
func DescriptionForDiscoverEKSIssue(issueType string) string {
return loadIssueDescription(issueType)
func DescriptionForDiscoverEKSIssue(issueType string) (string, string) {
return loadIssueTitleDescription(issueType)
}

// DescriptionForDiscoverRDSIssue returns the description of the issue and fixing steps.
// The returned string contains a markdown document.
// If issue type is not recognized or doesn't have a specific description, them an empty string is returned.
func DescriptionForDiscoverRDSIssue(issueType string) string {
return loadIssueDescription(issueType)
func DescriptionForDiscoverRDSIssue(issueType string) (string, string) {
return loadIssueTitleDescription(issueType)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SSM Agent lost connection
Auto enrolling EC2 instances requires the SSM Agent to be installed and running on them.
Some instances appear to have lost connection to Amazon Systems Manager.

Expand Down
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/ec2-ssm-agent-not-registered.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SSM Agent not registered
Auto enrolling EC2 instances requires the SSM Agent to be installed and running on them.
Some instances failed to connect to Amazon Systems Manager.

Expand Down
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/ec2-ssm-invocation-failure.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SSM Invocation failed
Teleport failed to access the SSM Agent to auto enroll the instance.
Some instances failed to communicate with the AWS Systems Manager service to execute the install script.

Expand Down
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/ec2-ssm-script-failure.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# SSM Script failure
Teleport was able to reach the SSM Agent inside the EC2 instance, however the install script returned an error.

You can click below in the Invocation URL and get further details on why the script failed.
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/ec2-ssm-unsupported-os.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Unsupported Operating System
Auto enrolling EC2 instances requires a compatible Operating System.

Teleport only supports Linux instances when auto-enrolling them into the cluster.
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/eks-agent-not-connecting.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Teleport Agent not connecting
The process of automatically enrolling EKS Clusters into Teleport, starts by installing the [`teleport-kube-agent`](https://goteleport.com/docs/reference/helm-reference/teleport-kube-agent/) to the cluster.

If the installation is successful, the EKS Cluster will appear in your Resources list.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Cluster authentication mode unsupported
Teleport uses the Amazon EKS API to install the Teleport Kubernetes Agent.

Please enable API (or API and Config Map) authentication mode in the following EKS Clusters so that they can be automatically enrolled.
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/eks-cluster-unreachable.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Unreachable cluster
The EKS Cluster must be accessible from the Teleport Auth Service in order for Teleport to deploy the Teleport Kubernetes Agent.

The following EKS Clusters couldn't be accessed.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Missing endpoint public access
The EKS Cluster must be publicly accessible in order for Teleport to deploy the Teleport Kubernetes Agent.

You can enable the public endpoint by accessing the Manage Endpoint Access.
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/eks-status-not-active.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Cluster status
Only EKS Clusters whose status is active can be automatically enrolled into teleport.

The following are not active.
1 change: 1 addition & 0 deletions lib/usertasks/descriptions/rds-iam-auth-disabled.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# IAM Auth disabled
The Teleport Database Service uses [IAM authentication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html) to communicate with RDS.

The following RDS databases do not have IAM authentication enabled.
Expand Down
18 changes: 10 additions & 8 deletions lib/usertasks/descriptions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ import (
)

func TestAllDescriptions(t *testing.T) {
for _, issueType := range usertasksapi.DiscoverEC2IssueTypes {
require.NotEmpty(t, DescriptionForDiscoverEC2Issue(issueType), "issue type %q is missing descriptions/%s.md file", issueType, issueType)
}
for _, issueType := range usertasksapi.DiscoverEKSIssueTypes {
require.NotEmpty(t, DescriptionForDiscoverEKSIssue(issueType), "issue type %q is missing descriptions/%s.md file", issueType, issueType)
}
for _, issueType := range usertasksapi.DiscoverRDSIssueTypes {
require.NotEmpty(t, DescriptionForDiscoverRDSIssue(issueType), "issue type %q is missing descriptions/%s.md file", issueType, issueType)
for _, issueGroup := range [][]string{
usertasksapi.DiscoverEC2IssueTypes,
usertasksapi.DiscoverEKSIssueTypes,
usertasksapi.DiscoverRDSIssueTypes,
} {
for _, issueType := range issueGroup {
title, description := DescriptionForDiscoverEC2Issue(issueType)
require.NotEmpty(t, title, "issue type %q is missing title in descriptions/%s.md file", issueType, issueType)
require.NotEmpty(t, description, "issue type %q is missing description in descriptions/%s.md file", issueType, issueType)
}
}
}
10 changes: 7 additions & 3 deletions lib/web/ui/usertask.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type UserTask struct {
type UserTaskDetail struct {
// UserTask has the basic fields that all tasks include.
UserTask
// Title is the issue title.
Title string `json:"title,omitempty"`
// Description is a markdown document that explains the issue and how to fix it.
Description string `json:"description,omitempty"`
// DiscoverEC2 contains the task details for the DiscoverEC2 tasks.
Expand Down Expand Up @@ -97,6 +99,7 @@ func MakeUserTasks(uts []*usertasksv1.UserTask) []UserTask {

// MakeDetailedUserTask creates a UI UserTask representation containing all the details.
func MakeDetailedUserTask(ut *usertasksv1.UserTask) UserTaskDetail {
var title string
var description string

var discoverEC2 *usertasks.UserTaskDiscoverEC2WithURLs
Expand All @@ -105,20 +108,21 @@ func MakeDetailedUserTask(ut *usertasksv1.UserTask) UserTaskDetail {

switch ut.GetSpec().GetTaskType() {
case apiusertasks.TaskTypeDiscoverEC2:
description = usertasks.DescriptionForDiscoverEC2Issue(ut.GetSpec().GetIssueType())
title, description = usertasks.DescriptionForDiscoverEC2Issue(ut.GetSpec().GetIssueType())
discoverEC2 = usertasks.EC2InstancesWithURLs(ut)

case apiusertasks.TaskTypeDiscoverEKS:
description = usertasks.DescriptionForDiscoverEKSIssue(ut.GetSpec().GetIssueType())
title, description = usertasks.DescriptionForDiscoverEKSIssue(ut.GetSpec().GetIssueType())
discoverEKS = usertasks.EKSClustersWithURLs(ut)

case apiusertasks.TaskTypeDiscoverRDS:
description = usertasks.DescriptionForDiscoverRDSIssue(ut.GetSpec().GetIssueType())
title, description = usertasks.DescriptionForDiscoverRDSIssue(ut.GetSpec().GetIssueType())
discoverRDS = usertasks.RDSDatabasesWithURLs(ut)
}

return UserTaskDetail{
UserTask: MakeUserTask(ut),
Title: title,
Description: description,
DiscoverEC2: discoverEC2,
DiscoverEKS: discoverEKS,
Expand Down
2 changes: 2 additions & 0 deletions lib/web/usertasks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ func TestUserTask(t *testing.T) {
err = json.Unmarshal(resp.Bytes(), &userTaskDetailResp)
require.NoError(t, err)
require.Equal(t, "OPEN", userTaskDetailResp.State)
require.NotEmpty(t, userTaskDetailResp.Description)
require.NotEmpty(t, userTaskDetailResp.Title)
require.NotEmpty(t, userTaskDetailResp.DiscoverEC2)
lastStateChangeT0 := userTaskDetailResp.LastStateChange

Expand Down
Loading