From d72a764b93b9b5c88b78d8748a88de58f4f4a492 Mon Sep 17 00:00:00 2001
From: Marco Dinis <marco.dinis@goteleport.com>
Date: Wed, 25 Sep 2024 11:45:47 -0700
Subject: [PATCH] Server auto discover: allow fips package

This PR changes auto discovery to use the fips package when using
fips-environments.

AFAIK, we dont support auto upgrade for fips environments.
---
 api/types/constants.go                        |  4 +-
 lib/srv/server/installer/autodiscover.go      |  8 +++-
 lib/srv/server/installer/autodiscover_test.go | 42 +++++++++++++++++++
 lib/web/apiserver.go                          |  7 +++-
 4 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/api/types/constants.go b/api/types/constants.go
index edbc133e98172..330053c94b1d8 100644
--- a/api/types/constants.go
+++ b/api/types/constants.go
@@ -40,6 +40,8 @@ const (
 	PackageNameOSS = "teleport"
 	// PackageNameEnt is the teleport package name for the Enterprise version.
 	PackageNameEnt = "teleport-ent"
+	// PackageNameEntFIPS is the teleport package name for the Enterprise with FIPS enabled version.
+	PackageNameEntFIPS = "teleport-ent-fips"
 
 	// ActionRead grants read access (get, list)
 	ActionRead = "read"
@@ -583,7 +585,7 @@ const (
 )
 
 // PackageNameKinds is the list of valid teleport package names.
-var PackageNameKinds = []string{PackageNameOSS, PackageNameEnt}
+var PackageNameKinds = []string{PackageNameOSS, PackageNameEnt, PackageNameEntFIPS}
 
 // WebSessionSubKinds lists subkinds of web session resources
 var WebSessionSubKinds = []string{KindAppSession, KindWebSession, KindSnowflakeSession, KindSAMLIdPSession}
diff --git a/lib/srv/server/installer/autodiscover.go b/lib/srv/server/installer/autodiscover.go
index 2597c2e05cf54..756336756c0b5 100644
--- a/lib/srv/server/installer/autodiscover.go
+++ b/lib/srv/server/installer/autodiscover.go
@@ -68,7 +68,7 @@ type AutoDiscoverNodeInstallerConfig struct {
 	ProxyPublicAddr string
 
 	// TeleportPackage contains the teleport package name.
-	// Allowed values: teleport, teleport-ent
+	// Allowed values: teleport, teleport-ent, teleport-ent-fips
 	TeleportPackage string
 
 	// RepositoryChannel is the repository channel to use.
@@ -129,10 +129,14 @@ func (c *AutoDiscoverNodeInstallerConfig) checkAndSetDefaults() error {
 		return trace.BadParameter("teleport-package must be one of %+v", types.PackageNameKinds)
 	}
 
-	if c.AutoUpgrades && c.TeleportPackage != types.PackageNameEnt {
+	if c.AutoUpgrades && c.TeleportPackage == types.PackageNameOSS {
 		return trace.BadParameter("only enterprise package supports auto upgrades")
 	}
 
+	if c.AutoUpgrades && c.TeleportPackage == types.PackageNameEntFIPS {
+		return trace.BadParameter("auto upgrades are not supported in FIPS environments")
+	}
+
 	if c.autoUpgradesChannelURL == "" {
 		c.autoUpgradesChannelURL = "https://" + c.ProxyPublicAddr + "/v1/webapi/automaticupgrades/channel/default"
 	}
diff --git a/lib/srv/server/installer/autodiscover_test.go b/lib/srv/server/installer/autodiscover_test.go
index 9a4e0e20475b9..36cc15687da8c 100644
--- a/lib/srv/server/installer/autodiscover_test.go
+++ b/lib/srv/server/installer/autodiscover_test.go
@@ -131,6 +131,48 @@ func TestAutoDiscoverNode(t *testing.T) {
 		},
 	}
 
+	t.Run("check and set defaults", func(t *testing.T) {
+		t.Run("oss package is not allowed with auto upgrades", func(t *testing.T) {
+			installerConfig := &AutoDiscoverNodeInstallerConfig{
+				RepositoryChannel: "stable/rolling",
+				AutoUpgrades:      true,
+				ProxyPublicAddr:   "proxy.example.com",
+				TeleportPackage:   "teleport",
+				TokenName:         "my-token",
+				AzureClientID:     "azure-client-id",
+			}
+
+			_, err := NewAutoDiscoverNodeInstaller(installerConfig)
+			require.Error(t, err)
+		})
+		t.Run("fips package is allowed", func(t *testing.T) {
+			installerConfig := &AutoDiscoverNodeInstallerConfig{
+				RepositoryChannel: "stable/rolling",
+				AutoUpgrades:      false,
+				ProxyPublicAddr:   "proxy.example.com",
+				TeleportPackage:   "teleport-ent-fips",
+				TokenName:         "my-token",
+				AzureClientID:     "azure-client-id",
+			}
+
+			_, err := NewAutoDiscoverNodeInstaller(installerConfig)
+			require.NoError(t, err)
+		})
+		t.Run("fips is not allowed with auto upgrades", func(t *testing.T) {
+			installerConfig := &AutoDiscoverNodeInstallerConfig{
+				RepositoryChannel: "stable/rolling",
+				AutoUpgrades:      true,
+				ProxyPublicAddr:   "proxy.example.com",
+				TeleportPackage:   "teleport-ent-fips",
+				TokenName:         "my-token",
+				AzureClientID:     "azure-client-id",
+			}
+
+			_, err := NewAutoDiscoverNodeInstaller(installerConfig)
+			require.Error(t, err)
+		})
+	})
+
 	t.Run("well known distros", func(t *testing.T) {
 		for distroName, distroVersions := range wellKnownOS {
 			for distroVersion, distroConfig := range distroVersions {
diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go
index b06d4e1554517..e99e0bcbb7f30 100644
--- a/lib/web/apiserver.go
+++ b/lib/web/apiserver.go
@@ -2080,9 +2080,12 @@ func (h *Handler) installer(w http.ResponseWriter, r *http.Request, p httprouter
 	}
 
 	feats := modules.GetModules().Features()
-	teleportPackage := teleport.ComponentTeleport
+	teleportPackage := types.PackageNameOSS
 	if modules.GetModules().BuildType() == modules.BuildEnterprise || feats.Cloud {
-		teleportPackage = fmt.Sprintf("%s-%s", teleport.ComponentTeleport, modules.BuildEnterprise)
+		teleportPackage = types.PackageNameEnt
+		if h.cfg.FIPS {
+			teleportPackage = types.PackageNameEntFIPS
+		}
 	}
 
 	// By default, it uses the stable/v<majorVersion> channel.