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

Teleport install command for discovery agents (go) #43423

Merged
merged 4 commits into from
Jul 9, 2024

Conversation

marcoandredinis
Copy link
Contributor

This PR adds a new command that will install teleport on the current system.
Its goal is to replace the default installer script used in Auto Discovery scripts.

Its correctness should be compared to the current script
https://github.com/gravitational/teleport/blob/master/api/types/installers/installer.sh.tmpl
Improvements will only be considered on a coming PR.

@marcoandredinis marcoandredinis added no-changelog Indicates that a PR does not require a changelog entry backport/branch/v15 backport/branch/v16 labels Jun 24, 2024
@github-actions github-actions bot requested review from kimlisa and lxea June 24, 2024 17:32
@public-teleport-github-review-bot

@marcoandredinis - this PR will require admin approval to merge due to its size. Consider breaking it up into a series smaller changes.

@marcoandredinis marcoandredinis force-pushed the marco/server-autodiscover-script-go branch from aadb50e to 4466762 Compare June 25, 2024 07:52
@marcoandredinis marcoandredinis force-pushed the marco/server-autodiscover-script-go branch 5 times, most recently from 6281e59 to 0cdf101 Compare June 25, 2024 15:35
@marcoandredinis marcoandredinis requested a review from r0mant June 25, 2024 16:51
@marcoandredinis marcoandredinis force-pushed the marco/server-autodiscover-script-go branch from 0cdf101 to 7e35c38 Compare June 28, 2024 13:14
Copy link
Collaborator

@r0mant r0mant left a comment

Choose a reason for hiding this comment

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

Looks pretty good to me, just left a few suggestions about reuse/organization.

lib/srv/server/installer/autodiscover.go Outdated Show resolved Hide resolved
Comment on lines 316 to 209
// Check if teleport is already installed.
if _, err := os.Stat(asi.binariesLocation.teleport); err == nil {
asi.Logger.InfoContext(ctx, "Teleport is already installed in the system.")
return nil
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can it happen that teleport binary is present but we failed to generate/write config (or it got removed for some reason)? In this case the method will not proceed but installation will not be valid.

Or are you planning to address this scenario in a follow-up PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I'm planning on multiple follow-up PRs
I'm tracking improvements on the 1st tasklist of this issue #37620

Feel free to add more improvements there 👍

return trace.Wrap(err)
}

// The last step is to configure the `teleport.yaml`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor-ish refactoring request. This function does 2 things: installs teleport and creates its configuration. Can these 2 things be factored out into corresponding methods (installTeleportPackage, configureTeleport)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes 👍

return imdsClient, nil
}

func (asi *AutodiscoverNodeInstaller) fetchTargetVersion(ctx context.Context) string {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We have the logic for dealing with automatic updates versions in lib/automaticupgrades/channel.go. Is this something that we can reuse (or possibly extend) instead of reimplementing it here?

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 already use the github.com/gravitational/teleport/lib/automaticupgrades/version package.

Aside from parsing the URL from string into net.URL we would call this method:

	targetVersion, err := version.NewBasicHTTPVersionGetter(upgradeURL).GetVersion(ctx)

@hugoShaka Is there something else we can add to the package?

return strings.TrimSpace(strings.TrimPrefix(targetVersion, "v"))
}

func fetchNodeAutoDiscoverLabels(ctx context.Context, imdsClient imds.Client) (map[string]string, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we already automatically fetch node labels on every cloud we support. Is this something we can reuse? cc @atburke would probably know.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For the record, this is the equivalent in the current shell script

if on_azure; then
API_VERSION=$(curl -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/versions" | jq -r ".apiVersions[-1]")
INSTANCE_INFO=$(curl -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=$API_VERSION&format=json")
REGION="$(echo "$INSTANCE_INFO" | jq -r .compute.location)"
RESOURCE_GROUP="$(echo "$INSTANCE_INFO" | jq -r .compute.resourceGroupName)"
SUBSCRIPTION_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.subscriptionId)"
VM_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.vmId)"
JOIN_METHOD=azure
LABELS="teleport.internal/vm-id=${VM_ID},teleport.internal/subscription-id=${SUBSCRIPTION_ID},teleport.internal/region=${REGION},teleport.internal/resource-group=${RESOURCE_GROUP}"
elif on_ec2; then
IMDS_TOKEN=$(curl -m5 -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
INSTANCE_INFO=$(curl -m5 -sS -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/dynamic/instance-identity/document")
ACCOUNT_ID="$(echo "$INSTANCE_INFO" | jq -r .accountId)"
INSTANCE_ID="$(echo "$INSTANCE_INFO" | jq -r .instanceId)"
JOIN_METHOD=iam
LABELS="teleport.dev/instance-id=${INSTANCE_ID},teleport.dev/account-id=${ACCOUNT_ID}"
elif on_gcp; then
NAME="$(curl -m5 -sS -H "Metadata-Flavor:Google" "http://metadata.google.internal/computeMetadata/v1/instance/name")"
# GCP metadata returns fully qualified zone ("projects/<project-id>/zones/<zone>"), so we need to parse the zone name.
FULL_ZONE="$(curl -m5 -sS -H "Metadata-Flavor:Google" "http://metadata.google.internal/computeMetadata/v1/instance/zone")"
ZONE="$(basename $FULL_ZONE)"
PROJECT_ID=$(curl -m5 -sS -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/project/project-id")
JOIN_METHOD=gcp
LABELS="teleport.internal/name=${NAME},teleport.internal/zone=${ZONE},teleport.internal/project-id=${PROJECT_ID}"
else
echo "Could not determine cloud provider"
exit 1
fi

These labels are not sourced from the instance's labels/tags. These are mostly metadata used for detecting already enrolled instances and some other metadata.

Let's use Azure as an example.
The script adds the following labels:

REGION="$(echo "$INSTANCE_INFO" | jq -r .compute.location)"
RESOURCE_GROUP="$(echo "$INSTANCE_INFO" | jq -r .compute.resourceGroupName)"
SUBSCRIPTION_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.subscriptionId)"
VM_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.vmId)"
JOIN_METHOD=azure
LABELS="teleport.internal/vm-id=${VM_ID},teleport.internal/subscription-id=${SUBSCRIPTION_ID},teleport.internal/region=${REGION},teleport.internal/resource-group=${RESOURCE_GROUP}"

The following labels are used to detect if the instance is already enrolled:

labels := n.GetAllLabels()
_, subscriptionOK := labels[types.SubscriptionIDLabel]
_, vmOK := labels[types.VMIDLabel]
return subscriptionOK && vmOK

So, we end up with a couple more labels which might be used for RBAC.
Some of those labels are not present in any go code, and that's why I ended up adding them here
https://github.com/gravitational/teleport/blob/7e35c38679a71601234305baffa3cfa83c5b5fa3/api/types/constants.go#L675-L682

@atburke Can you please double check this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, that's all correct.

*linux.OSRelease
}

func (l *linuxDistroInfo) packageManagerKind() packageManagerKind {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: What do you think about moving this (along with all related logic/structs/constants) somewhere to utils package? Feels like this could be useful outside of just installer in future e.g. for the next-gen auto-updates work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved things to lib/utils/packagemanager/ and removed some not-required types/methods.

@marcoandredinis marcoandredinis force-pushed the marco/server-autodiscover-script-go branch 2 times, most recently from 6ea8381 to 26b461a Compare July 3, 2024 13:33
@marcoandredinis
Copy link
Contributor Author

@kimlisa @lxea Can you please take a look when you get a chance?

@marcoandredinis marcoandredinis force-pushed the marco/server-autodiscover-script-go branch 3 times, most recently from ed0aadb to 79f6551 Compare July 8, 2024 09:33
lib/srv/server/installer/autodiscover.go Outdated Show resolved Hide resolved
lib/srv/server/installer/autodiscover.go Outdated Show resolved Hide resolved
lib/srv/server/installer/autodiscover.go Outdated Show resolved Hide resolved
tool/teleport/common/teleport.go Outdated Show resolved Hide resolved
@marcoandredinis marcoandredinis force-pushed the marco/server-autodiscover-script-go branch 2 times, most recently from 00b86d3 to ad519e9 Compare July 9, 2024 09:54
@marcoandredinis marcoandredinis enabled auto-merge July 9, 2024 09:56
This PR adds a new command that will install teleport on the current
system.
Its goal is to replace the default installer script used in Auto
Discovery scripts.

Its correctness should be compared to the current script. Improvements
will only be considered on a 2nd phase.
@marcoandredinis marcoandredinis force-pushed the marco/server-autodiscover-script-go branch from ad519e9 to 731b3dc Compare July 9, 2024 10:16
@marcoandredinis marcoandredinis added this pull request to the merge queue Jul 9, 2024
Merged via the queue into master with commit fe4418f Jul 9, 2024
38 checks passed
@marcoandredinis marcoandredinis deleted the marco/server-autodiscover-script-go branch July 9, 2024 10:52
@public-teleport-github-review-bot

@marcoandredinis See the table below for backport results.

Branch Result
branch/v15 Create PR
branch/v16 Create PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport/branch/v16 no-changelog Indicates that a PR does not require a changelog entry size/xl
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants