diff --git a/cmd/fleetctl/fleetctl/apply_test.go b/cmd/fleetctl/fleetctl/apply_test.go
index 3d32bf9f1d..249ad5a201 100644
--- a/cmd/fleetctl/fleetctl/apply_test.go
+++ b/cmd/fleetctl/fleetctl/apply_test.go
@@ -40,6 +40,15 @@ import (
"github.com/urfave/cli/v2"
)
+var testSAMLIDPMetadataURL = getTestSAMLIDPMetadataURL()
+
+func getTestSAMLIDPMetadataURL() string {
+ if port := os.Getenv("FLEET_SAML_IDP_HTTP_PORT"); port != "" {
+ return "http://localhost:" + port + "/simplesaml/saml2/idp/metadata.php"
+ }
+ return "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+}
+
var userRoleSpecList = []*fleet.User{
{
UpdateCreateTimestamps: fleet.UpdateCreateTimestamps{
@@ -3619,7 +3628,7 @@ spec:
},
{
desc: "missing required sso entity_id",
- spec: `
+ spec: fmt.Sprintf(`
apiVersion: v1
kind: config
spec:
@@ -3628,13 +3637,13 @@ spec:
entity_id: ""
issuer_uri: "http://localhost:8080/simplesaml/saml2/idp/SSOService.php"
idp_name: "SimpleSAML"
- metadata_url: "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
-`,
+ metadata_url: "%s"
+`, testSAMLIDPMetadataURL),
wantErr: `422 Validation Failed: required`,
},
{
desc: "missing required sso idp_name",
- spec: `
+ spec: fmt.Sprintf(`
apiVersion: v1
kind: config
spec:
@@ -3643,8 +3652,8 @@ spec:
entity_id: "https://localhost:8080"
issuer_uri: "http://localhost:8080/simplesaml/saml2/idp/SSOService.php"
idp_name: ""
- metadata_url: "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
-`,
+ metadata_url: "%s"
+`, testSAMLIDPMetadataURL),
wantErr: `422 Validation Failed: required`,
},
{
diff --git a/docker-compose.yml b/docker-compose.yml
index f32e4378cf..17e42eeaad 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -26,7 +26,7 @@ services:
# This is required by Percona XtraDB server.
CLUSTER_NAME: fleet
ports:
- - "3306:3306"
+ - "${FLEET_MYSQL_PORT:-3306}:3306"
mysql_test:
image: ${FLEET_MYSQL_IMAGE:-mysql:8.0.44}
@@ -76,7 +76,7 @@ services:
environment: *mysql-default-environment
ports:
# ports 3308 and 3309 are used by the main and replica MySQL containers in tools/mysql-replica-testing/docker-compose.yml
- - "3310:3306"
+ - "${FLEET_MYSQL_REPLICA_TEST_PORT:-3310}:3306"
tmpfs:
- /var/lib/mysql:rw,noexec,nosuid
- /tmpfs
@@ -85,15 +85,15 @@ services:
mailhog:
image: mailhog/mailhog:latest
ports:
- - "8025:8025"
- - "1025:1025"
+ - "${FLEET_MAILHOG_WEB_PORT:-8025}:8025"
+ - "${FLEET_MAILHOG_SMTP_PORT:-1025}:1025"
# SMTP server with Basic Authentication.
mailpit:
image: axllent/mailpit:latest
ports:
- - "8026:8025"
- - "1026:1025"
+ - "${FLEET_MAILPIT_WEB_PORT:-8026}:8025"
+ - "${FLEET_MAILPIT_SMTP_PORT:-1026}:1025"
volumes:
- ./tools/mailpit/auth.txt:/auth.txt
command: ["--smtp-auth-file=/auth.txt", "--smtp-auth-allow-insecure=true"]
@@ -102,8 +102,8 @@ services:
smtp4dev_test:
image: rnwood/smtp4dev:v3
ports:
- - "8028:80"
- - "1027:25"
+ - "${FLEET_SMTP4DEV_WEB_PORT:-8028}:80"
+ - "${FLEET_SMTP4DEV_SMTP_PORT:-1027}:25"
volumes:
- ./tools/smtp4dev:/certs
environment:
@@ -114,7 +114,7 @@ services:
redis:
image: redis:6
ports:
- - "6379:6379"
+ - "${FLEET_REDIS_PORT:-6379}:6379"
saml_idp:
image: fleetdm/docker-idp:latest
@@ -122,15 +122,15 @@ services:
- ./tools/saml/users.php:/var/www/simplesamlphp/config/authsources.php
- ./tools/saml/config.php:/var/www/simplesamlphp/metadata/saml20-sp-remote.php
ports:
- - "9080:8080"
- - "9443:8443"
+ - "${FLEET_SAML_IDP_HTTP_PORT:-9080}:8080"
+ - "${FLEET_SAML_IDP_HTTPS_PORT:-9443}:8443"
# CAdvisor container allows monitoring other containers. Useful for
# development.
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- - "5678:8080"
+ - "${FLEET_CADVISOR_PORT:-5678}:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /sys:/sys:ro
@@ -139,7 +139,7 @@ services:
prometheus:
image: prom/prometheus:latest
ports:
- - "9090:9090"
+ - "${FLEET_PROMETHEUS_PORT:-9090}:9090"
volumes:
- ./tools/app/prometheus.yml:/etc/prometheus/prometheus.yml
@@ -148,8 +148,8 @@ services:
localstack:
image: localstack/localstack
ports:
- - "4566:4566"
- - "4571:4571"
+ - "${FLEET_LOCALSTACK_PORT:-4566}:4566"
+ - "${FLEET_LOCALSTACK_LEGACY_PORT:-4571}:4571"
environment:
- SERVICES=firehose,kinesis,s3,iam,sts,secretsmanager
@@ -157,8 +157,8 @@ services:
s3:
image: rustfs/rustfs:1.0.0-alpha.85
ports:
- - "9000:9000"
- - "9001:9001"
+ - "${FLEET_S3_PORT:-9000}:9000"
+ - "${FLEET_S3_CONSOLE_PORT:-9001}:9001"
environment:
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
diff --git a/server/datastore/s3/testing_utils.go b/server/datastore/s3/testing_utils.go
index f15dd092cd..35784f66b5 100644
--- a/server/datastore/s3/testing_utils.go
+++ b/server/datastore/s3/testing_utils.go
@@ -15,9 +15,17 @@ import (
const (
accessKeyID = "locals3"
secretAccessKey = "locals3"
- testEndpoint = "http://localhost:9000"
)
+var testEndpoint = getTestEndpoint()
+
+func getTestEndpoint() string {
+ if port := os.Getenv("FLEET_S3_PORT"); port != "" {
+ return "http://localhost:" + port
+ }
+ return "http://localhost:9000"
+}
+
func SetupTestSoftwareInstallerStore(tb testing.TB, bucket, prefix string) *SoftwareInstallerStore {
store := setupTestStore(tb, bucket, prefix, NewSoftwareInstallerStore)
tb.Cleanup(func() { cleanupStore(tb, store.s3store) })
diff --git a/server/mail/mail_test.go b/server/mail/mail_test.go
index 110072f9f5..11545aa85f 100644
--- a/server/mail/mail_test.go
+++ b/server/mail/mail_test.go
@@ -7,6 +7,7 @@ import (
"io"
"net/http"
"os"
+ "strconv"
"testing"
"time"
@@ -18,6 +19,35 @@ import (
"github.com/stretchr/testify/require"
)
+var testMailpitSMTPPort = getTestMailpitSMTPPort()
+var testMailpitWebURL = getTestMailpitWebURL()
+var testSMTP4DevSMTPPort = getTestSMTP4DevSMTPPort()
+
+func getTestMailpitSMTPPort() uint {
+ if port := os.Getenv("FLEET_MAILPIT_SMTP_PORT"); port != "" {
+ if p, err := strconv.ParseUint(port, 10, 32); err == nil && p > 0 {
+ return uint(p)
+ }
+ }
+ return 1026
+}
+
+func getTestMailpitWebURL() string {
+ if port := os.Getenv("FLEET_MAILPIT_WEB_PORT"); port != "" {
+ return "http://127.0.0.1:" + port
+ }
+ return "http://127.0.0.1:8026"
+}
+
+func getTestSMTP4DevSMTPPort() uint {
+ if port := os.Getenv("FLEET_SMTP4DEV_SMTP_PORT"); port != "" {
+ if p, err := strconv.ParseUint(port, 10, 32); err == nil && p > 0 {
+ return uint(p)
+ }
+ }
+ return 1027
+}
+
var testFunctions = [...]func(*testing.T, fleet.MailService){
testSMTPPlainAuth,
testSMTPPlainAuthInvalidCreds,
@@ -37,7 +67,7 @@ func TestCanSendMail(t *testing.T) {
SMTPEnableTLS: false,
SMTPVerifySSLCerts: false,
SMTPEnableStartTLS: false,
- SMTPPort: 1026,
+ SMTPPort: testMailpitSMTPPort,
SMTPServer: "localhost",
SMTPSenderAddress: "test@example.com",
}
@@ -49,8 +79,8 @@ func TestCanSendMail(t *testing.T) {
}
func TestMail(t *testing.T) {
- // This mail test requires mailhog unauthenticated running on localhost:1025
- // and mailpit running on localhost:1026.
+ // This mail test requires mailhog and mailpit (ports read from env vars
+ // FLEET_MAILPIT_SMTP_PORT, FLEET_SMTP4DEV_SMTP_PORT, FLEET_MAILPIT_WEB_PORT).
if _, ok := os.LookupEnv("MAIL_TEST"); !ok {
t.Skip("Mail tests are disabled")
}
@@ -78,7 +108,7 @@ func testSMTPPlainAuth(t *testing.T, mailer fleet.MailService) {
SMTPEnableTLS: false,
SMTPVerifySSLCerts: false,
SMTPEnableStartTLS: false,
- SMTPPort: 1026,
+ SMTPPort: testMailpitSMTPPort,
SMTPServer: "localhost",
SMTPSenderAddress: "test@example.com",
},
@@ -104,7 +134,7 @@ func testSMTPPlainAuthInvalidCreds(t *testing.T, mailer fleet.MailService) {
SMTPEnableTLS: false,
SMTPVerifySSLCerts: false,
SMTPEnableStartTLS: false,
- SMTPPort: 1026,
+ SMTPPort: testMailpitSMTPPort,
SMTPServer: "localhost",
SMTPSenderAddress: "test@example.com",
},
@@ -130,7 +160,7 @@ func testSMTPSkipVerify(t *testing.T, mailer fleet.MailService) {
SMTPEnableTLS: true,
SMTPVerifySSLCerts: false,
SMTPEnableStartTLS: true,
- SMTPPort: 1027,
+ SMTPPort: testSMTP4DevSMTPPort,
SMTPServer: "localhost",
SMTPSenderAddress: "test@example.com",
},
@@ -153,7 +183,7 @@ func testSMTPNoAuthWithTLS(t *testing.T, mailer fleet.MailService) {
SMTPEnableTLS: true,
SMTPVerifySSLCerts: true,
SMTPEnableStartTLS: true,
- SMTPPort: 1027,
+ SMTPPort: testSMTP4DevSMTPPort,
SMTPServer: "localhost",
SMTPSenderAddress: "test@example.com",
},
@@ -181,7 +211,7 @@ func testSMTPDomain(t *testing.T, mailer fleet.MailService) {
SMTPEnableTLS: false,
SMTPVerifySSLCerts: false,
SMTPEnableStartTLS: false,
- SMTPPort: 1026,
+ SMTPPort: testMailpitSMTPPort,
SMTPServer: "localhost",
SMTPDomain: "custom.domain.example.com",
SMTPSenderAddress: randomAddress,
@@ -221,7 +251,7 @@ type MailpitMessages struct {
}
func getLastRawMailpitMessageFrom(t *testing.T, address string) string {
- res, err := http.Get("http://127.0.0.1:8026/api/v1/messages")
+ res, err := http.Get(testMailpitWebURL + "/api/v1/messages")
require.NoError(t, err)
var messages MailpitMessages
@@ -236,7 +266,7 @@ func getLastRawMailpitMessageFrom(t *testing.T, address string) string {
}
require.NotNilf(t, messageID, "could not find message from %s in mailpit", address)
- res, err = http.Get(fmt.Sprintf("http://127.0.0.1:8026/api/v1/message/%s/raw", messageID))
+ res, err = http.Get(fmt.Sprintf("%s/api/v1/message/%s/raw", testMailpitWebURL, messageID))
require.NoError(t, err)
rawMail, err := io.ReadAll(res.Body)
@@ -258,7 +288,7 @@ func testMailTest(t *testing.T, mailer fleet.MailService) {
SMTPEnableTLS: true,
SMTPVerifySSLCerts: true,
SMTPEnableStartTLS: true,
- SMTPPort: 1027,
+ SMTPPort: testSMTP4DevSMTPPort,
SMTPServer: "localhost",
SMTPSenderAddress: "test@example.com",
},
diff --git a/server/platform/mysql/testing_utils/testing_utils.go b/server/platform/mysql/testing_utils/testing_utils.go
index ed48e85246..a48c6103ec 100644
--- a/server/platform/mysql/testing_utils/testing_utils.go
+++ b/server/platform/mysql/testing_utils/testing_utils.go
@@ -20,9 +20,19 @@ const (
TestUsername = "root"
TestPassword = "toor"
TestReplicaDatabaseSuffix = "_replica"
- TestReplicaAddress = "localhost:3310"
)
+var TestReplicaAddress = getTestReplicaAddress()
+
+// getTestReplicaAddress returns the MySQL replica test server address from environment variable
+// FLEET_MYSQL_REPLICA_TEST_PORT or defaults to localhost:3310
+func getTestReplicaAddress() string {
+ if port := os.Getenv("FLEET_MYSQL_REPLICA_TEST_PORT"); port != "" {
+ return "localhost:" + port
+ }
+ return "localhost:3310"
+}
+
var TestAddress = getTestAddress()
// getTestAddress returns the MySQL test server address from environment variable
diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go
index 0fa44d1167..768de98b2b 100644
--- a/server/service/integration_enterprise_test.go
+++ b/server/service/integration_enterprise_test.go
@@ -4868,7 +4868,7 @@ func (s *integrationEnterpriseTestSuite) TestSSOJITProvisioning() {
t := s.T()
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -4876,10 +4876,10 @@ func (s *integrationEnterpriseTestSuite) TestSSOJITProvisioning() {
"enable_sso": true,
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php",
+ "metadata_url": "%s",
"enable_jit_provisioning": false
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
require.False(t, acResp.SSOSettings.EnableJITProvisioning)
@@ -4895,15 +4895,15 @@ func (s *integrationEnterpriseTestSuite) TestSSOJITProvisioning() {
// enable JIT provisioning
acResp = appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"sso_settings": {
"enable_sso": true,
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php",
+ "metadata_url": "%s",
"enable_jit_provisioning": true
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
require.True(t, acResp.SSOSettings.EnableJITProvisioning)
@@ -21075,7 +21075,7 @@ func (s *integrationEnterpriseTestSuite) TestSSOIdPInitiatedLogin() {
t := s.T()
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -21085,9 +21085,9 @@ func (s *integrationEnterpriseTestSuite) TestSSOIdPInitiatedLogin() {
"enable_sso_idp_login": true,
"entity_id": "sso.test.com",
"idp_name": "SimpleSAML",
- "metadata_url": "http://127.0.0.1:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
body := s.LoginSSOUserIDPInitiated("sso_user2", "user123#", "sso.test.com")
diff --git a/server/service/integration_mdm_dep_test.go b/server/service/integration_mdm_dep_test.go
index 2d5ca1344a..c1a7baba96 100644
--- a/server/service/integration_mdm_dep_test.go
+++ b/server/service/integration_mdm_dep_test.go
@@ -95,18 +95,18 @@ func (s *integrationMDMTestSuite) TestDEPEnrollReleaseDeviceGlobal() {
// setup IdP so that AccountConfiguration profile is sent after DEP enrollment
var acResp appConfigResponse
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotEmpty(t, acResp.MDM.EndUserAuthentication)
t.Cleanup(func() {
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
@@ -264,13 +264,13 @@ func (s *integrationMDMTestSuite) TestDEPEnrollReleaseDeviceTeam() {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true
}
}
- }`, "fleet_ade_test", tm.Name, tm.Name, tm.Name)), http.StatusOK, &acResp)
+ }`, "fleet_ade_test", tm.Name, tm.Name, tm.Name, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotEmpty(t, acResp.MDM.EndUserAuthentication)
t.Cleanup(func() {
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go
index c25996b88f..66428ab207 100644
--- a/server/service/integration_mdm_test.go
+++ b/server/service/integration_mdm_test.go
@@ -4819,15 +4819,15 @@ func (s *integrationMDMTestSuite) TestMDMMacOSSetup() {
// setup test data
var acResp appConfigResponse
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotEmpty(t, acResp.MDM.EndUserAuthentication)
tm, err := s.ds.NewTeam(context.Background(), &fleet.Team{Name: "team1"})
@@ -5205,18 +5205,18 @@ func (s *integrationMDMTestSuite) TestMDMMacOSSetup() {
var acResp appConfigResponse
var errResp validationErrResp
var teamResp teamResponse
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotEmpty(t, acResp.MDM.EndUserAuthentication)
// can't clear IdP settings while end user authentication is enabled (global)
@@ -5258,15 +5258,15 @@ func (s *integrationMDMTestSuite) TestMDMMacOSSetup() {
// can't clear IdP settings while end user authentication is enabled on a team
// 1. configure IdP globally
acResp = appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotEmpty(t, acResp.MDM.EndUserAuthentication)
require.False(t, acResp.MDM.MacOSSetup.EnableEndUserAuthentication)
@@ -6275,7 +6275,7 @@ func (s *integrationMDMTestSuite) TestSSO() {
// "mdm.test.com" entity ID is defined in `tools/saml/config.php`.
acResp = appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -6283,14 +6283,14 @@ func (s *integrationMDMTestSuite) TestSSO() {
"end_user_authentication": {
"entity_id": "mdm.test.com",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true,
"lock_end_user_info": true
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
s.runWorker()
require.Contains(t, lastSubmittedProfile.URL, acResp.ServerSettings.ServerURL+"/mdm/sso")
@@ -7074,7 +7074,7 @@ func (s *integrationMDMTestSuite) setUpMDMSSO(t *testing.T, lockEndUserInfo bool
// set the SSO fields
acResp = appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -7082,18 +7082,18 @@ func (s *integrationMDMTestSuite) setUpMDMSSO(t *testing.T, lockEndUserInfo bool
"end_user_authentication": {
"entity_id": "mdm.test.com",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true,
- "lock_end_user_info": `+fmt.Sprintf("%t", lockEndUserInfo)+`
+ "lock_end_user_info": %t
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL, lockEndUserInfo)), http.StatusOK, &acResp)
wantSettings := fleet.SSOProviderSettings{
EntityID: "mdm.test.com",
IDPName: "SimpleSAML",
- MetadataURL: "http://localhost:9080/simplesaml/saml2/idp/metadata.php",
+ MetadataURL: testSAMLIDPMetadataURL,
}
assert.Equal(t, wantSettings, acResp.MDM.EndUserAuthentication.SSOProviderSettings)
@@ -11102,18 +11102,18 @@ func (s *integrationMDMTestSuite) TestCustomConfigurationWebURL() {
// configure end-user authentication globally
acResp = appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
// assign the DEP profile and assert that contains the right values for the URL
configurationWebURLShouldBeEmpty = false
@@ -11167,18 +11167,18 @@ func (s *integrationMDMTestSuite) TestCustomConfigurationWebURL() {
// try to enable end user auth again, it fails because configuration_web_url is set
acResp = appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true
}
}
- }`), http.StatusUnprocessableEntity, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusUnprocessableEntity, &acResp)
// create a team via spec
teamSpecs := map[string]any{
@@ -11207,18 +11207,18 @@ func (s *integrationMDMTestSuite) TestCustomConfigurationWebURL() {
err = s.ds.DeleteMDMAppleSetupAssistant(context.Background(), nil)
require.NoError(t, err)
acResp = appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"mdm": {
"end_user_authentication": {
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
},
"macos_setup": {
"enable_end_user_authentication": true
}
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
// enable end user auth
teamSpecs = map[string]any{
@@ -19943,7 +19943,7 @@ func (s *integrationMDMTestSuite) TestBYODEnrollmentWithIdPEnabled() {
res = s.DoRawNoAuth("GET", "/enroll", nil, http.StatusSeeOther, "enroll_secret", "idp")
location := res.Header.Get("Location")
require.NotEmpty(t, location)
- require.True(t, strings.HasPrefix(location, "http://localhost:9080/simplesaml/"))
+ require.True(t, strings.HasPrefix(location, testSAMLIDPBaseURL+"/simplesaml/"))
res = s.LoginMDMSSOUser("sso_user", "user123#")
require.Equal(t, http.StatusSeeOther, res.StatusCode)
@@ -19958,7 +19958,7 @@ func (s *integrationMDMTestSuite) TestBYODEnrollmentWithIdPEnabled() {
map[string]string{"Cookie": shared_mdm.BYODIdpCookieName + "=abc"}, "enroll_secret", "idp", "enrollment_reference", "not_matching!")
location = res.Header.Get("Location")
require.NotEmpty(t, location)
- require.True(t, strings.HasPrefix(location, "http://localhost:9080/simplesaml/"))
+ require.True(t, strings.HasPrefix(location, testSAMLIDPBaseURL+"/simplesaml/"))
// requesting the /enroll page again and simulating the BYOD IdP cookie being
// set renders the download profile page when there is a matching enrollment
@@ -19974,7 +19974,7 @@ func (s *integrationMDMTestSuite) TestBYODEnrollmentWithIdPEnabled() {
res = s.DoRawNoAuth("GET", "/enroll", nil, http.StatusSeeOther, "enroll_secret", "no-such-secret")
location = res.Header.Get("Location")
require.NotEmpty(t, location)
- require.True(t, strings.HasPrefix(location, "http://localhost:9080/simplesaml/"))
+ require.True(t, strings.HasPrefix(location, testSAMLIDPBaseURL+"/simplesaml/"))
}
func (s *integrationMDMTestSuite) TestIOSiPadOSRefetch() {
@@ -21425,7 +21425,7 @@ func (s *integrationMDMTestSuite) TestTechnicianPermissions() {
// Set SMTP, agent options, and SSO settings, and check they are not available for Technicians.
acSetup := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"smtp_settings": {
"enable_smtp": true,
"sender_address": "test@example.com",
@@ -21439,7 +21439,7 @@ func (s *integrationMDMTestSuite) TestTechnicianPermissions() {
"enable_sso": true,
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php",
+ "metadata_url": "%s",
"enable_jit_provisioning": false
},
"agent_options": {
@@ -21455,7 +21455,7 @@ func (s *integrationMDMTestSuite) TestTechnicianPermissions() {
}
}
}
- }`), http.StatusOK, &acSetup)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acSetup)
t.Cleanup(func() {
acSetup := appConfigResponse{}
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
diff --git a/server/service/integration_sso_test.go b/server/service/integration_sso_test.go
index 5c10c1b312..0145a05d54 100644
--- a/server/service/integration_sso_test.go
+++ b/server/service/integration_sso_test.go
@@ -61,15 +61,15 @@ func (s *integrationSSOTestSuite) TestGetSSOSettings() {
t := s.T()
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"sso_settings": {
"enable_sso": true,
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php",
+ "metadata_url": "%s",
"enable_jit_provisioning": false
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
// double-check the settings
@@ -167,7 +167,7 @@ func (s *integrationSSOTestSuite) TestSSOLogin() {
t := s.T()
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -175,9 +175,9 @@ func (s *integrationSSOTestSuite) TestSSOLogin() {
"enable_sso": true,
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
// Register current number of activities.
@@ -270,7 +270,7 @@ func (s *integrationSSOTestSuite) TestSSOLoginDisallowedWithPremiumRoles() {
t := s.T()
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -278,9 +278,9 @@ func (s *integrationSSOTestSuite) TestSSOLoginDisallowedWithPremiumRoles() {
"enable_sso": true,
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
user, err := s.ds.UserByEmail(t.Context(), "sso_user2@example.com")
@@ -344,14 +344,14 @@ func (s *integrationSSOTestSuite) TestPerformRequiredPasswordResetWithSSO() {
// enable SSO
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"sso_settings": {
"enable_sso": true,
"entity_id": "https://localhost:8080",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
// perform a required password change using the non-SSO user, works
@@ -403,8 +403,8 @@ func (s *integrationSSOTestSuite) TestSSOLoginWithMetadata() {
t := s.T()
acResp := appConfigResponse{}
- metadata, err := json.Marshal([]byte(`
-
+ metadata, err := json.Marshal(fmt.Appendf(nil, `
+
@@ -420,11 +420,11 @@ func (s *integrationSSOTestSuite) TestSSOLoginWithMetadata() {
-
+
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
-
+
-`))
+`, testSAMLIDPMetadataURL, testSAMLIDPSLOURL, testSAMLIDPSSOURL))
require.NoError(t, err)
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
@@ -461,7 +461,7 @@ func (s *integrationSSOTestSuite) TestSSOLoginNoEntityID() {
t := s.T()
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -469,9 +469,9 @@ func (s *integrationSSOTestSuite) TestSSOLoginNoEntityID() {
"enable_sso": true,
"entity_id": "localhost",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
ac, err := s.ds.AppConfig(context.Background())
@@ -506,7 +506,7 @@ func (s *integrationSSOTestSuite) TestSSOLoginSAMLResponseTampered() {
}
acResp := appConfigResponse{}
- s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
+ s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(fmt.Sprintf(`{
"server_settings": {
"server_url": "https://localhost:8080"
},
@@ -514,9 +514,9 @@ func (s *integrationSSOTestSuite) TestSSOLoginSAMLResponseTampered() {
"enable_sso": true,
"entity_id": "sso.test.com",
"idp_name": "SimpleSAML",
- "metadata_url": "http://localhost:9080/simplesaml/saml2/idp/metadata.php"
+ "metadata_url": "%s"
}
- }`), http.StatusOK, &acResp)
+ }`, testSAMLIDPMetadataURL)), http.StatusOK, &acResp)
require.NotNil(t, acResp)
// Create sso_user2@example.com if it doesn't exist (because this is
@@ -588,9 +588,9 @@ func (s *integrationSSOTestSuite) TestSSOLoginSAMLResponseTampered() {
func (s *integrationSSOTestSuite) TestSSOServerURL() {
t := s.T()
- // Use the test metadata instead of trying to fetch from localhost:9080
- testMetadata := `
-
+ // Use the test metadata instead of trying to fetch from the SAML IDP
+ testMetadata := fmt.Sprintf(`
+
@@ -599,11 +599,11 @@ func (s *integrationSSOTestSuite) TestSSOServerURL() {
-
+
urn:oasis:names:tc:SAML:2.0:nameid-format:transient
-
+
-`
+`, testSAMLIDPMetadataURL, testSAMLIDPSLOURL, testSAMLIDPSSOURL)
// Configure SSO with a specific SSO server URL and inline metadata
acResp := appConfigResponse{}
diff --git a/server/service/mail_test.go b/server/service/mail_test.go
index 488a2b6d74..d7bcc949cc 100644
--- a/server/service/mail_test.go
+++ b/server/service/mail_test.go
@@ -8,6 +8,7 @@ import (
"io"
"net/http"
"os"
+ "strconv"
"testing"
"github.com/fleetdm/fleet/v4/server/fleet"
@@ -18,6 +19,25 @@ import (
"gopkg.in/guregu/null.v3"
)
+var testMailpitSMTPPort = getTestMailpitSMTPPort()
+var testMailpitWebURL = getTestMailpitWebURL()
+
+func getTestMailpitSMTPPort() uint {
+ if port := os.Getenv("FLEET_MAILPIT_SMTP_PORT"); port != "" {
+ if p, err := strconv.ParseUint(port, 10, 32); err == nil && p > 0 {
+ return uint(p)
+ }
+ }
+ return 1026
+}
+
+func getTestMailpitWebURL() string {
+ if port := os.Getenv("FLEET_MAILPIT_WEB_PORT"); port != "" {
+ return "http://127.0.0.1:" + port
+ }
+ return "http://127.0.0.1:8026"
+}
+
type notTestFoundError struct{}
func (e *notTestFoundError) Error() string {
@@ -40,7 +60,7 @@ func (e *notTestFoundError) Is(other error) bool {
}
func TestMailService(t *testing.T) {
- // This mail test requires mailpit running on localhost:1026.
+ // This mail test requires mailpit (ports read from env vars FLEET_MAILPIT_SMTP_PORT, FLEET_MAILPIT_WEB_PORT).
if _, ok := os.LookupEnv("MAIL_TEST"); !ok {
t.Skip("Mail tests are disabled")
}
@@ -61,7 +81,7 @@ func TestMailService(t *testing.T) {
SMTPPassword: "mailpit-password",
SMTPEnableTLS: false,
SMTPVerifySSLCerts: false,
- SMTPPort: 1026,
+ SMTPPort: testMailpitSMTPPort,
SMTPServer: "localhost",
SMTPSenderAddress: "foobar@example.com",
},
@@ -101,7 +121,7 @@ func TestMailService(t *testing.T) {
ctx = test.UserContext(ctx, test.UserAdmin)
// (1) Modifying the app config `sender_address` field to trigger a test e-mail send.
- _, err := svc.ModifyAppConfig(ctx, []byte(`{
+ _, err := svc.ModifyAppConfig(ctx, fmt.Appendf(nil, `{
"org_info": {
"org_name": "Acme"
},
@@ -117,15 +137,15 @@ func TestMailService(t *testing.T) {
"password": "mailpit-password",
"enable_ssl_tls": false,
"verify_ssl_certs": false,
- "port": 1026,
+ "port": %d,
"server": "127.0.0.1",
"sender_address": "foobar_updated@example.com"
}
-}`), fleet.ApplySpecOptions{})
+}`, testMailpitSMTPPort), fleet.ApplySpecOptions{})
require.NoError(t, err)
getLastMailPitMessage := func() map[string]interface{} {
- resp, err := http.Get("http://localhost:8026/api/v1/messages?limit=1")
+ resp, err := http.Get(testMailpitWebURL + "/api/v1/messages?limit=1")
require.NoError(t, err)
defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
diff --git a/server/service/testing_client.go b/server/service/testing_client.go
index 4196a4f260..7f4ed2190e 100644
--- a/server/service/testing_client.go
+++ b/server/service/testing_client.go
@@ -38,6 +38,19 @@ import (
"github.com/stretchr/testify/suite"
)
+// testSAMLIDPBaseURL is the SAML IDP base URL, read from FLEET_SAML_IDP_HTTP_PORT (defaults to http://localhost:9080).
+var testSAMLIDPBaseURL = getTestSAMLIDPBaseURL()
+var testSAMLIDPMetadataURL = testSAMLIDPBaseURL + "/simplesaml/saml2/idp/metadata.php"
+var testSAMLIDPSSOURL = testSAMLIDPBaseURL + "/simplesaml/saml2/idp/SSOService.php"
+var testSAMLIDPSLOURL = testSAMLIDPBaseURL + "/simplesaml/saml2/idp/SingleLogoutService.php"
+
+func getTestSAMLIDPBaseURL() string {
+ if port := os.Getenv("FLEET_SAML_IDP_HTTP_PORT"); port != "" {
+ return "http://localhost:" + port
+ }
+ return "http://localhost:9080"
+}
+
type withDS struct {
s *suite.Suite
ds *mysql.Datastore
@@ -455,7 +468,7 @@ func (ts *withServer) LoginSSOUserIDPInitiated(username, password, entityID stri
res := ts.loginSSOUserIDPInitiated(
username, password,
"/api/v1/fleet/sso",
- fmt.Sprintf("http://127.0.0.1:9080/simplesaml/saml2/idp/SSOService.php?spentityid=%s", entityID),
+ fmt.Sprintf("%s?spentityid=%s", testSAMLIDPSSOURL, entityID),
http.StatusOK,
)
defer res.Body.Close()