Only allow FLEET_DEV_* env vars when --dev is passed, allow overriding configs one at a time in dev (#38652)

Resolves #38484. This includes a CI job change to make sure we don't
introduce any more env vars that don't get proxied (and thus turned off
outside `--dev`).

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)

## Testing

- [x] Added/updated automated tests

Manual QA touched hot paths, but did _not_ manually test every
FLEET_DEV_* environment variable change.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Centralized dev-mode environment management for consistent FLEET_DEV_*
handling and test-friendly overrides.
* Dev-mode allows targeted overrides for certain dev-only configuration
when running with --dev.

* **Chores**
* Migrated environment access to the centralized dev-mode helper across
the codebase.
  * Added CI checks to enforce proper usage of FLEET_DEV_* variables.

* **Documentation**
  * Added guidance on dev-mode environment variable rules and overrides.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Victor Lyuboslavsky <2685025+getvictor@users.noreply.github.com>
This commit is contained in:
Ian Littman
2026-01-27 14:32:56 -06:00
committed by GitHub
co-authored by Victor Lyuboslavsky
parent 89c35709ef
commit 2f25580c3a
40 changed files with 239 additions and 165 deletions
+18
View File
@@ -78,6 +78,24 @@ jobs:
run: |
go run ./tools/cloner-check/main.go -check
- name: Ensure all FLEET_DEV_* env var accesses are proxied
run: |
if grep -R 'os.Getenv("FLEET_DEV' --include="*.go" .; then
echo "Error: Found unproxied FLEET_DEV_* env var access. Please proxy via dev_mode.Env()." >&2
exit 1
else
echo "OK: No unproxied FLEET_DEV_* env var accesses found."
fi
- name: Restrict FLEET_DEV_* env var overrides to test code only
run: |
if grep -R 'SetOverride("FLEET_DEV' --include="*.go" --exclude="*_test.go" --exclude="testing_utils.go" --exclude-dir="mdmtest" .; then
echo "Error: Found FLEET_DEV_* overrides in non-test code." >&2
exit 1
else
echo "OK: No FLEET_DEV_* overrides in non-test code."
fi
golangci-incremental:
# Only run on pull requests (needs base branch for incremental comparison)
if: github.event_name == 'pull_request'
+2
View File
@@ -0,0 +1,2 @@
* Disallowed use of FLEET_DEV_* environment variables unless `--dev` is passed when serving Fleet.
* Allowed overriding individual configuration variables for MySQL and object storage when `--dev` is passed when serving Fleet.
+2 -1
View File
@@ -20,6 +20,7 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/license"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm"
"github.com/fleetdm/fleet/v4/server/mdm/android"
@@ -1452,7 +1453,7 @@ func newMDMAPNsPusher(
const name = string(fleet.CronAppleMDMAPNsPusher)
interval := 1 * time.Minute
if intervalEnv := os.Getenv("FLEET_DEV_CUSTOM_APNS_PUSHER_INTERVAL"); intervalEnv != "" {
if intervalEnv := dev_mode.Env("FLEET_DEV_CUSTOM_APNS_PUSHER_INTERVAL"); intervalEnv != "" {
var err error
interval, err = time.ParseDuration(intervalEnv)
if err != nil {
+28 -25
View File
@@ -93,37 +93,40 @@ wish to override the default value.
}
func applyDevFlags(cfg *config.FleetConfig) {
cfg.Mysql.Username = "fleet"
cfg.Mysql.Database = "fleet"
cfg.Mysql.Password = "insecure"
if cfg.Prometheus.BasicAuth.Username == "" {
cfg.Prometheus.BasicAuth.Username = "fleet"
}
if cfg.Prometheus.BasicAuth.Password == "" {
cfg.Prometheus.BasicAuth.Password = "insecure"
// set database and object storage configs to work with local docker-compose setup if a given value is missing
setIfEmpty := func(target *string, value string) {
if *target == "" {
*target = value
}
}
// Allow the carves bucket to be overridden in dev mode
if cfg.S3.CarvesBucket == "" {
cfg.S3.CarvesBucket = "carves-dev"
cfg.S3.CarvesRegion = "localhost"
cfg.S3.CarvesPrefix = "dev-prefix"
cfg.S3.CarvesEndpointURL = "http://localhost:9000"
cfg.S3.CarvesAccessKeyID = "locals3"
cfg.S3.CarvesSecretAccessKey = "locals3"
setIfEmpty(&cfg.Mysql.Username, "fleet")
setIfEmpty(&cfg.Mysql.Database, "fleet")
setIfEmpty(&cfg.Mysql.Password, "insecure")
setIfEmpty(&cfg.Prometheus.BasicAuth.Username, "fleet")
setIfEmpty(&cfg.Prometheus.BasicAuth.Password, "insecure")
setIfEmpty(&cfg.S3.CarvesBucket, "carves-dev")
setIfEmpty(&cfg.S3.CarvesRegion, "localhost")
setIfEmpty(&cfg.S3.CarvesPrefix, "dev-prefix")
setIfEmpty(&cfg.S3.CarvesEndpointURL, "http://localhost:9000")
setIfEmpty(&cfg.S3.CarvesAccessKeyID, "locals3")
setIfEmpty(&cfg.S3.CarvesSecretAccessKey, "locals3")
if cfg.S3.CarvesAccessKeyID == "locals3" && cfg.S3.CarvesSecretAccessKey == "locals3" {
// can't rely on zero values
cfg.S3.CarvesDisableSSL = true
cfg.S3.CarvesForceS3PathStyle = true
}
// Allow the software installers bucket to be overridden in dev mode
if cfg.S3.SoftwareInstallersBucket == "" {
cfg.S3.SoftwareInstallersBucket = "software-installers-dev"
cfg.S3.SoftwareInstallersRegion = "localhost"
cfg.S3.SoftwareInstallersPrefix = "dev-prefix"
cfg.S3.SoftwareInstallersEndpointURL = "http://localhost:9000"
cfg.S3.SoftwareInstallersAccessKeyID = "locals3"
cfg.S3.SoftwareInstallersSecretAccessKey = "locals3"
setIfEmpty(&cfg.S3.SoftwareInstallersBucket, "software-installers-dev")
setIfEmpty(&cfg.S3.SoftwareInstallersRegion, "localhost")
setIfEmpty(&cfg.S3.SoftwareInstallersPrefix, "dev-prefix")
setIfEmpty(&cfg.S3.SoftwareInstallersEndpointURL, "http://localhost:9000")
setIfEmpty(&cfg.S3.SoftwareInstallersAccessKeyID, "locals3")
setIfEmpty(&cfg.S3.SoftwareInstallersSecretAccessKey, "locals3")
if cfg.S3.SoftwareInstallersAccessKeyID == "locals3" && cfg.S3.SoftwareInstallersSecretAccessKey == "locals3" {
// can't rely on zero values
cfg.S3.SoftwareInstallersDisableSSL = true
cfg.S3.SoftwareInstallersForceS3PathStyle = true
}
+4 -5
View File
@@ -9,6 +9,7 @@ import (
"github.com/WatchBeam/clock"
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/spf13/cobra"
)
@@ -28,8 +29,6 @@ To setup Fleet infrastructure, use one of the available commands.
}
noPrompt := false
// Whether to enable developer options
dev := false
// Whether to show table stats before and after the migration
showTableStats := false
@@ -40,7 +39,7 @@ To setup Fleet infrastructure, use one of the available commands.
Run: func(cmd *cobra.Command, args []string) {
config := configManager.LoadConfig()
if dev {
if dev_mode.IsEnabled {
applyDevFlags(&config)
noPrompt = true
}
@@ -100,7 +99,7 @@ To setup Fleet infrastructure, use one of the available commands.
printFleetv4732UnknownStateMessage(status.StatusCode)
case fleet.UnknownMigrations:
printUnknownMigrationsMessage(status.UnknownTable, status.UnknownData)
if dev {
if dev_mode.IsEnabled {
os.Exit(1)
}
}
@@ -118,7 +117,7 @@ To setup Fleet infrastructure, use one of the available commands.
}
dbCmd.PersistentFlags().BoolVar(&noPrompt, "no-prompt", false, "disable prompting before migrations (for use in scripts)")
dbCmd.PersistentFlags().BoolVar(&dev, "dev", false, "Enable developer options")
dbCmd.PersistentFlags().BoolVar(&dev_mode.IsEnabled, "dev", false, "Enable developer options")
dbCmd.PersistentFlags().BoolVar(&showTableStats, "with-table-stats", false, "Show approximate table row counts after migrations")
prepareCmd.AddCommand(dbCmd)
+7 -8
View File
@@ -48,6 +48,7 @@ import (
"github.com/fleetdm/fleet/v4/server/datastore/mysqlredis"
"github.com/fleetdm/fleet/v4/server/datastore/redis"
"github.com/fleetdm/fleet/v4/server/datastore/s3"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/errorstore"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/health"
@@ -119,8 +120,6 @@ type initializer interface {
func createServeCmd(configManager configpkg.Manager) *cobra.Command {
// Whether to enable the debug endpoints
debug := false
// Whether to enable developer options
dev := false
// Whether to enable development Fleet Premium license
devLicense := false
// Whether to enable development Fleet Premium license with an expired license
@@ -140,7 +139,7 @@ the way that the Fleet server works.
Run: func(cmd *cobra.Command, args []string) {
config := configManager.LoadConfig()
if dev {
if dev_mode.IsEnabled {
applyDevFlags(&config)
}
@@ -158,7 +157,7 @@ the way that the Fleet server works.
logger := initLogger(config)
if dev {
if dev_mode.IsEnabled {
createTestBuckets(&config, logger)
}
@@ -276,7 +275,7 @@ the way that the Fleet server works.
opts = append(opts, mysql.Replica(&config.MysqlReadReplica))
}
// NOTE this will disable OTEL/APM interceptor
if dev && os.Getenv("FLEET_DEV_ENABLE_SQL_INTERCEPTOR") != "" {
if dev_mode.Env("FLEET_DEV_ENABLE_SQL_INTERCEPTOR") != "" {
opts = append(opts, mysql.WithInterceptor(&devSQLInterceptor{
logger: kitlog.With(logger, "component", "sql-interceptor"),
}))
@@ -317,7 +316,7 @@ the way that the Fleet server works.
// OK
case fleet.UnknownMigrations:
printUnknownMigrationsMessage(migrationStatus.UnknownTable, migrationStatus.UnknownData)
if dev {
if dev_mode.IsEnabled {
os.Exit(1)
}
case fleet.NeedsFleetv4732Fix:
@@ -563,7 +562,7 @@ the way that the Fleet server works.
Certificates: []tls.Certificate{*cert},
})), nil
}))
if os.Getenv("FLEET_DEV_MDM_APPLE_DISABLE_PUSH") == "1" {
if dev_mode.Env("FLEET_DEV_MDM_APPLE_DISABLE_PUSH") == "1" {
mdmPushService = nopPusher{}
} else {
mdmPushService = nanomdm_pushsvc.New(mdmStorage, mdmStorage, pushProviderFactory, nanoMDMLogger)
@@ -1710,7 +1709,7 @@ the way that the Fleet server works.
}
serveCmd.PersistentFlags().BoolVar(&debug, "debug", false, "Enable debug endpoints")
serveCmd.PersistentFlags().BoolVar(&dev, "dev", false, "Enable developer options")
serveCmd.PersistentFlags().BoolVar(&dev_mode.IsEnabled, "dev", false, "Enable developer options")
serveCmd.PersistentFlags().BoolVar(&devLicense, "dev_license", false, "Enable development license")
serveCmd.PersistentFlags().BoolVar(&devExpiredLicense, "dev_expired_license", false, "Enable expired development license")
+3 -3
View File
@@ -8,6 +8,7 @@ import (
"time"
"github.com/fleetdm/fleet/v4/server/contexts/license"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/WatchBeam/clock"
"github.com/fleetdm/fleet/v4/server/config"
@@ -19,7 +20,6 @@ import (
)
var (
dev bool
devLicense bool
devExpiredLicense bool
lockDuration time.Duration
@@ -36,7 +36,7 @@ will disable it on the server allowing the user configure their own 'cron' mecha
by an exit code of zero.`,
RunE: func(cmd *cobra.Command, args []string) (err error) {
cfg := configManager.LoadConfig()
if dev {
if dev_mode.IsEnabled {
applyDevFlags(&cfg)
}
@@ -123,7 +123,7 @@ by an exit code of zero.`,
return
},
}
vulnProcessingCmd.PersistentFlags().BoolVar(&dev, "dev", false, "Enable developer options")
vulnProcessingCmd.PersistentFlags().BoolVar(&dev_mode.IsEnabled, "dev", false, "Enable developer options")
vulnProcessingCmd.PersistentFlags().BoolVar(&devLicense, "dev_license", false, "Enable development license")
vulnProcessingCmd.PersistentFlags().BoolVar(&devExpiredLicense, "dev_expired_license", false, "Enable expired development license")
vulnProcessingCmd.PersistentFlags().DurationVar(
@@ -15,6 +15,7 @@ import (
"testing"
"github.com/fleetdm/fleet/v4/pkg/optjson"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/ghodss/yaml"
@@ -785,8 +786,7 @@ func configureFMAManifestServer(t *testing.T) {
require.NoError(t, err)
}))
t.Cleanup(manifestServer.Close)
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
t.Cleanup(func() { os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL") })
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL, t)
}
func TestGenerateGitops(t *testing.T) {
@@ -20,6 +20,7 @@ import (
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/datastore/cached_mysql"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/mdm/apple/vpp"
@@ -643,7 +644,7 @@ func StartVPPApplyServer(t *testing.T, config *AppleVPPConfigSrvConf) {
_, _ = w.Write(resp)
}))
t.Setenv("FLEET_DEV_VPP_URL", srv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", srv.URL, t)
t.Cleanup(srv.Close)
}
@@ -748,8 +749,8 @@ func StartAndServeVPPServer(t *testing.T) {
t.Cleanup(vppProxySrv.Close)
t.Cleanup(vppProxyAuthSrv.Close)
t.Setenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", vppProxySrv.URL)
t.Setenv("FLEET_DEV_VPP_PROXY_AUTH_URL", vppProxyAuthSrv.URL)
dev_mode.SetOverride("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", vppProxySrv.URL, t)
dev_mode.SetOverride("FLEET_DEV_VPP_PROXY_AUTH_URL", vppProxyAuthSrv.URL, t)
}
type MockPusher struct{}
@@ -27,6 +27,7 @@ import (
"github.com/fleetdm/fleet/v4/server/datastore/filesystem"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/datastore/redis/redistest"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
appleMdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/mdm/nanodep/tokenpki"
@@ -2495,8 +2496,7 @@ team_settings:
}))
t.Cleanup(manifestServer.Close)
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL, t)
mysql.ExecAdhocSQL(t, s.DS, func(q sqlx.ExtContext) error {
_, err := q.ExecContext(ctx, `INSERT INTO fleet_maintained_apps (name, slug, platform, unique_identifier)
+2 -1
View File
@@ -18,6 +18,7 @@ import (
"github.com/crewjam/saml"
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/service/middleware/log"
"github.com/fleetdm/fleet/v4/server/service/middleware/otel"
@@ -591,7 +592,7 @@ func (s *idpService) buildSSOServerURL(ctx context.Context) (string, error) {
}
// Use the AppConfig method to build the SSO URL
ssoURL, err := appConfig.ConditionalAccessIdPSSOURL(os.Getenv)
ssoURL, err := appConfig.ConditionalAccessIdPSSOURL(dev_mode.Env)
if err != nil {
return "", ctxerr.Wrap(ctx, err, "build conditional access SSO URL")
}
+2 -2
View File
@@ -13,7 +13,6 @@ import (
"fmt"
"math/big"
"net/http"
"os"
"strconv"
"strings"
@@ -21,6 +20,7 @@ import (
"github.com/fleetdm/fleet/v4/ee/server/service/hostidentity/types"
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/assets"
scepdepot "github.com/fleetdm/fleet/v4/server/mdm/scep/depot"
@@ -54,7 +54,7 @@ func (e *RateLimitError) StatusCode() int { return http.StatusTooManyRequests }
// It checks for FLEET_DEV_HOST_IDENTITY_CERT_VALIDITY_DAYS environment variable
// and falls back to scepValidityDays if not set or invalid.
func getCertValidityDays() int {
if envValue := os.Getenv("FLEET_DEV_HOST_IDENTITY_CERT_VALIDITY_DAYS"); envValue != "" {
if envValue := dev_mode.Env("FLEET_DEV_HOST_IDENTITY_CERT_VALIDITY_DAYS"); envValue != "" {
if days, err := strconv.Atoi(envValue); err == nil && days > 0 {
return days
}
+2 -2
View File
@@ -3,7 +3,6 @@ package service
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"time"
@@ -14,6 +13,7 @@ import (
"github.com/fleetdm/fleet/v4/server/authz"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
maintained_apps "github.com/fleetdm/fleet/v4/server/mdm/maintainedapps"
"github.com/go-kit/kit/log/level"
@@ -71,7 +71,7 @@ func (svc *Service) AddFleetMaintainedApp(
// Download installer from the URL
timeout := maintained_apps.InstallerTimeout
if v := os.Getenv("FLEET_DEV_MAINTAINED_APPS_INSTALLER_TIMEOUT"); v != "" {
if v := dev_mode.Env("FLEET_DEV_MAINTAINED_APPS_INSTALLER_TIMEOUT"); v != "" {
timeout, _ = time.ParseDuration(v)
}
client := fleethttp.NewClient(fleethttp.WithTimeout(timeout))
+4 -6
View File
@@ -17,6 +17,7 @@ import (
"github.com/fleetdm/fleet/v4/server/authz"
authz_ctx "github.com/fleetdm/fleet/v4/server/contexts/authz"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mock"
"github.com/fleetdm/fleet/v4/server/ptr"
@@ -226,8 +227,7 @@ func TestGetMaintainedAppAuth(t *testing.T) {
}
var forbiddenError *authz.Forbidden
require.NoError(t, os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL))
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL, t)
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
ctx := viewer.NewContext(context.Background(), viewer.Viewer{User: tt.user})
@@ -330,8 +330,7 @@ func TestAddFleetMaintainedApp(t *testing.T) {
}))
t.Cleanup(manifestServer.Close)
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL, t)
svc := newTestService(t, ds)
@@ -411,8 +410,7 @@ func TestExtractMaintainedAppVersionWhenLatest(t *testing.T) {
}))
t.Cleanup(manifestServer.Close)
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL, t)
svc := newTestService(t, ds)
@@ -19,6 +19,7 @@ import (
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/datastore/s3"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
"github.com/fleetdm/fleet/v4/server/mock"
@@ -247,7 +248,6 @@ func TestInstallSoftwareTitle(t *testing.T) {
}
func TestSoftwareInstallerPayloadFromSlug(t *testing.T) {
t.Parallel()
ds := new(mock.Store)
svc := newTestService(t, ds)
@@ -296,8 +296,7 @@ func TestSoftwareInstallerPayloadFromSlug(t *testing.T) {
require.NoError(t, err)
}))
t.Cleanup(manifestServer.Close)
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL, t)
ds.GetMaintainedAppBySlugFunc = func(ctx context.Context, slug string, teamID *uint) (*fleet.MaintainedApp, error) {
return &fleet.MaintainedApp{
+3 -2
View File
@@ -6,7 +6,8 @@ import (
"fmt"
"net/http"
"net/url"
"os"
"github.com/fleetdm/fleet/v4/server/dev_mode"
)
type Metadata struct {
@@ -19,7 +20,7 @@ type Metadata struct {
}
func getBaseURL() string {
devURL := os.Getenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL")
devURL := dev_mode.Env("FLEET_DEV_DOWNLOAD_FLEETDM_URL")
if devURL != "" {
return devURL
}
+7 -6
View File
@@ -6,12 +6,13 @@ import (
"net/http/httptest"
"testing"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/stretchr/testify/require"
)
func TestGetBaseURL(t *testing.T) {
t.Run("with env variable", func(t *testing.T) {
t.Setenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL", "https://download-testing.fleetdm.com")
dev_mode.SetOverride("FLEET_DEV_DOWNLOAD_FLEETDM_URL", "https://download-testing.fleetdm.com", t)
require.Equal(t, "https://download-testing.fleetdm.com", getBaseURL())
})
@@ -37,7 +38,7 @@ func TestGetMetadata(t *testing.T) {
require.NoError(t, json.NewEncoder(w).Encode(expectedMetadata))
}))
t.Cleanup(server.Close)
t.Setenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL", server.URL)
dev_mode.SetOverride("FLEET_DEV_DOWNLOAD_FLEETDM_URL", server.URL, t)
meta, err := GetMetadata()
require.NoError(t, err)
@@ -46,7 +47,7 @@ func TestGetMetadata(t *testing.T) {
func TestGetMetadataErrorScenarios(t *testing.T) {
t.Run("invalid URL", func(t *testing.T) {
t.Setenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL", "://invalid-url")
dev_mode.SetOverride("FLEET_DEV_DOWNLOAD_FLEETDM_URL", "://invalid-url", t)
_, err := GetMetadata()
require.Error(t, err)
require.Contains(t, err.Error(), "invalid URL")
@@ -57,7 +58,7 @@ func TestGetMetadataErrorScenarios(t *testing.T) {
w.WriteHeader(http.StatusInternalServerError)
}))
t.Cleanup(server.Close)
t.Setenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL", server.URL)
dev_mode.SetOverride("FLEET_DEV_DOWNLOAD_FLEETDM_URL", server.URL, t)
_, err := GetMetadata()
require.Error(t, err)
@@ -72,7 +73,7 @@ func TestGetMetadataErrorScenarios(t *testing.T) {
require.NoError(t, err)
}))
t.Cleanup(server.Close)
t.Setenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL", server.URL)
dev_mode.SetOverride("FLEET_DEV_DOWNLOAD_FLEETDM_URL", server.URL, t)
_, err := GetMetadata()
require.Error(t, err)
@@ -82,7 +83,7 @@ func TestGetMetadataErrorScenarios(t *testing.T) {
func TestGetPKGManifestURL(t *testing.T) {
t.Run("with env variable", func(t *testing.T) {
t.Setenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL", "https://download-test.fleetdm.com")
dev_mode.SetOverride("FLEET_DEV_DOWNLOAD_FLEETDM_URL", "https://download-test.fleetdm.com", t)
require.Equal(t, "https://download-test.fleetdm.com/stable/fleetd-base-manifest.plist", GetPKGManifestURL())
})
+4 -2
View File
@@ -24,6 +24,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
shared_mdm "github.com/fleetdm/fleet/v4/pkg/mdm"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
@@ -538,16 +539,17 @@ func (c *TestAppleMDMClient) fetchOTAProfile(url string) error {
// believe this could be done with a little bit of reverse
// engineering/cleverness but for now, we're signing the request with
// our mock certs and setting this env var to skip the verification.
os.Setenv("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY", "1")
mockedCert, mockedKey, err := apple_mdm.NewSCEPCACertKey()
if err != nil {
return fmt.Errorf("creating mock certificates: %w", err)
}
dev_mode.SetOverride("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY", "1")
body, err = do(mockedCert, mockedKey)
dev_mode.ClearOverride("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY")
if err != nil {
return fmt.Errorf("first OTA request: %w", err)
}
os.Unsetenv("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY")
var scepInfo struct {
PayloadContent []struct {
+43
View File
@@ -0,0 +1,43 @@
package dev_mode
import (
"os"
"testing"
)
var IsEnabled bool
var envOverrides = map[string]string{}
type GetEnv func(name string) string
func Env(name string) string {
if !IsEnabled {
return ""
}
if override, ok := envOverrides[name]; ok {
return override
}
return os.Getenv(name)
}
func SetOverride(name string, value string, cleanup ...*testing.T) { // optional parameter to reset on test cleanup
if len(cleanup) > 0 {
cleanup[0].Setenv("FLEET_DEV_OVERRIDE_SET", "1") // triggers test deny-parallel check
cleanup[0].Cleanup(func() {
ClearOverride(name)
})
}
IsEnabled = true // if we're setting overrides, we're in a test environment so want to turn dev mode on
envOverrides[name] = value
}
func ClearOverride(name string) {
delete(envOverrides, name)
}
func ClearAllOverrides() {
envOverrides = map[string]string{}
}
+2 -1
View File
@@ -16,6 +16,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/optjson"
"github.com/fleetdm/fleet/v4/pkg/rawjson"
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/ptr"
)
@@ -288,7 +289,7 @@ func (c *AppConfig) MDMUrl() string {
// - https://foo.example.com:8080 -> https://okta.foo.example.com:8080
//
// Returns an error if the server URL is not configured or cannot be parsed.
func (c *AppConfig) ConditionalAccessIdPSSOURL(getenv func(string) string) (string, error) {
func (c *AppConfig) ConditionalAccessIdPSSOURL(getenv dev_mode.GetEnv) (string, error) {
// Check for dev override
if devURL := getenv("FLEET_DEV_OKTA_SSO_SERVER_URL"); devURL != "" {
return devURL, nil
@@ -12,6 +12,7 @@ import (
"cloud.google.com/go/pubsub"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/android"
"github.com/go-json-experiment/json"
@@ -35,7 +36,7 @@ type GoogleClient struct {
// Compile-time check to ensure that ProxyClient implements Client.
var _ Client = &GoogleClient{}
func NewGoogleClient(ctx context.Context, logger kitlog.Logger, getenv func(string) string) Client {
func NewGoogleClient(ctx context.Context, logger kitlog.Logger, getenv dev_mode.GetEnv) Client {
androidServiceCredentials := getenv("FLEET_DEV_ANDROID_GOOGLE_SERVICE_CREDENTIALS")
if androidServiceCredentials == "" {
return nil
@@ -13,6 +13,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/mdm/android"
"github.com/go-json-experiment/json"
kitlog "github.com/go-kit/log"
@@ -36,7 +37,7 @@ type ProxyClient struct {
// Compile-time check to ensure that ProxyClient implements Client.
var _ Client = &ProxyClient{}
func NewProxyClient(ctx context.Context, logger kitlog.Logger, licenseKey string, getenv func(string) string) Client {
func NewProxyClient(ctx context.Context, logger kitlog.Logger, licenseKey string, getenv dev_mode.GetEnv) Client {
proxyEndpoint := getenv("FLEET_DEV_ANDROID_PROXY_ENDPOINT")
if proxyEndpoint == "" {
proxyEndpoint = defaultProxyEndpoint
+5 -4
View File
@@ -8,7 +8,6 @@ import (
"fmt"
"net/http"
"net/url"
"os"
"strings"
"time"
@@ -19,6 +18,7 @@ import (
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/android"
"github.com/fleetdm/fleet/v4/server/mdm/android/service/androidmgmt"
@@ -110,10 +110,11 @@ func NewServiceWithClient(
func newAMAPIClient(ctx context.Context, logger kitlog.Logger, licenseKey string) androidmgmt.Client {
var client androidmgmt.Client
if os.Getenv("FLEET_DEV_ANDROID_GOOGLE_CLIENT") == "1" || strings.ToUpper(os.Getenv("FLEET_DEV_ANDROID_GOOGLE_CLIENT")) == "ON" {
client = androidmgmt.NewGoogleClient(ctx, logger, os.Getenv)
getEnv := dev_mode.Env
if getEnv("FLEET_DEV_ANDROID_GOOGLE_CLIENT") == "1" || strings.ToUpper(getEnv("FLEET_DEV_ANDROID_GOOGLE_CLIENT")) == "ON" {
client = androidmgmt.NewGoogleClient(ctx, logger, getEnv)
} else {
client = androidmgmt.NewProxyClient(ctx, logger, licenseKey, os.Getenv)
client = androidmgmt.NewProxyClient(ctx, logger, licenseKey, getEnv)
}
return client
}
+8 -8
View File
@@ -8,7 +8,6 @@ import (
"io"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
@@ -16,6 +15,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/pkg/retry"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
)
@@ -244,14 +244,14 @@ func ToVPPApps(app Metadata) map[fleet.InstallableDevicePlatform]fleet.VPPApp {
func getBaseURL() string {
region := "us"
if os.Getenv("FLEET_DEV_VPP_REGION") != "" {
region = os.Getenv("FLEET_DEV_VPP_REGION")
if dev_mode.Env("FLEET_DEV_VPP_REGION") != "" {
region = dev_mode.Env("FLEET_DEV_VPP_REGION")
}
if os.Getenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL") == "apple" {
if dev_mode.Env("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL") == "apple" {
return fmt.Sprintf(appleHostAndScheme+"/v1/catalog/%s/stoken-authenticated-apps?platform=iphone&additionalPlatforms=ipad,mac&extend[apps]=latestVersionInfo", region)
}
if os.Getenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL") != "" {
return os.Getenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL")
if dev_mode.Env("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL") != "" {
return dev_mode.Env("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL")
}
return fmt.Sprintf("https://fleetdm.com/api/vpp/v1/metadata/%s?platform=iphone&additionalPlatforms=ipad,mac&extend[apps]=latestVersionInfo", region)
}
@@ -266,7 +266,7 @@ type DataStore interface {
}
func GetAuthenticator(ctx context.Context, ds DataStore, licenseKey string) Authenticator {
token := os.Getenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN")
token := dev_mode.Env("FLEET_DEV_VPP_METADATA_BEARER_TOKEN")
if token != "" {
return func(bool) (string, error) { return token, nil }
}
@@ -281,7 +281,7 @@ func GetAuthenticator(ctx context.Context, ds DataStore, licenseKey string) Auth
}
}
authUrl := os.Getenv("FLEET_DEV_VPP_PROXY_AUTH_URL")
authUrl := dev_mode.Env("FLEET_DEV_VPP_PROXY_AUTH_URL")
if authUrl == "" {
authUrl = "https://fleetdm.com/api/vpp/v1/auth"
}
+20 -27
View File
@@ -6,18 +6,19 @@ import (
"io"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/jmoiron/sqlx"
"github.com/stretchr/testify/require"
)
func TestGetBaseURLAndBuildMetadataRequest(t *testing.T) {
defer dev_mode.ClearAllOverrides()
t.Run("Default URL", func(t *testing.T) {
os.Setenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", "")
dev_mode.SetOverride("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", "", t)
require.Equal(t, "https://fleetdm.com/api/vpp/v1/metadata/us?platform=iphone&additionalPlatforms=ipad,mac&extend[apps]=latestVersionInfo", getBaseURL())
req, err := buildMetadataRequest([]string{"1"}, "this-is-a-token")
@@ -28,7 +29,7 @@ func TestGetBaseURLAndBuildMetadataRequest(t *testing.T) {
t.Run("Custom URL", func(t *testing.T) {
customURL := "http://localhost:8000"
os.Setenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", customURL)
dev_mode.SetOverride("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", customURL, t)
require.Equal(t, customURL, getBaseURL())
req, err := buildMetadataRequest([]string{"1"}, "this-is-a-token")
@@ -38,14 +39,14 @@ func TestGetBaseURLAndBuildMetadataRequest(t *testing.T) {
})
t.Run("Custom Region", func(t *testing.T) {
os.Setenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", "")
os.Setenv("FLEET_DEV_VPP_REGION", "fr")
dev_mode.SetOverride("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", "", t)
dev_mode.SetOverride("FLEET_DEV_VPP_REGION", "fr", t)
require.Equal(t, "https://fleetdm.com/api/vpp/v1/metadata/fr?platform=iphone&additionalPlatforms=ipad,mac&extend[apps]=latestVersionInfo", getBaseURL())
})
t.Run("Direct to Apple", func(t *testing.T) {
os.Setenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", "apple")
os.Setenv("FLEET_DEV_VPP_REGION", "")
dev_mode.SetOverride("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", "apple", t)
dev_mode.SetOverride("FLEET_DEV_VPP_REGION", "", t)
require.Equal(t, "https://api.ent.apple.com/v1/catalog/us/stoken-authenticated-apps?platform=iphone&additionalPlatforms=ipad,mac&extend[apps]=latestVersionInfo", getBaseURL())
req, err := buildMetadataRequest([]string{"1"}, "this-is-a-token")
@@ -57,7 +58,7 @@ func TestGetBaseURLAndBuildMetadataRequest(t *testing.T) {
func setupFakeServer(t *testing.T, handler http.HandlerFunc) {
server := httptest.NewServer(handler)
os.Setenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", server.URL)
dev_mode.SetOverride("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL", server.URL, t)
t.Cleanup(server.Close)
}
@@ -233,16 +234,8 @@ func (m *mockDataStore) GetAllCAConfigAssetsByType(ctx context.Context, assetTyp
func TestAuthentication(t *testing.T) {
// Clear any dev env vars that might interfere
originalDevToken := os.Getenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN")
originalAuthURL := os.Getenv("FLEET_DEV_VPP_PROXY_AUTH_URL")
t.Cleanup(func() {
os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", originalDevToken)
os.Setenv("FLEET_DEV_VPP_PROXY_AUTH_URL", originalAuthURL)
})
t.Run("uses bearer token env var when set", func(t *testing.T) {
os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "dev-test-token")
defer os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "")
dev_mode.SetOverride("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "dev-test-token", t)
ds := &mockDataStore{}
auth := GetAuthenticator(context.Background(), ds, "license-key")
@@ -261,7 +254,7 @@ func TestAuthentication(t *testing.T) {
})
t.Run("returns cached token from database when not forced renewal", func(t *testing.T) {
os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "")
dev_mode.SetOverride("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "", t)
ds := &mockDataStore{
assets: map[fleet.MDMAssetName]fleet.MDMConfigAsset{
@@ -281,7 +274,7 @@ func TestAuthentication(t *testing.T) {
})
t.Run("requests new token when forced renewal even if cached exists", func(t *testing.T) {
os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "")
dev_mode.SetOverride("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "", t)
// Set up a mock auth server
authServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -294,7 +287,7 @@ func TestAuthentication(t *testing.T) {
_, _ = w.Write([]byte(`{"fleetServerSecret": "new-token-from-auth"}`))
}))
defer authServer.Close()
os.Setenv("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL, t)
ds := &mockDataStore{
assets: map[fleet.MDMAssetName]fleet.MDMConfigAsset{
@@ -326,7 +319,7 @@ func TestAuthentication(t *testing.T) {
})
t.Run("requests new token when nothing in database and no forced renewal", func(t *testing.T) {
os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "")
dev_mode.SetOverride("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "", t)
// Set up a mock auth server
authServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -339,7 +332,7 @@ func TestAuthentication(t *testing.T) {
_, _ = w.Write([]byte(`{"fleetServerSecret": "fresh-token"}`))
}))
defer authServer.Close()
os.Setenv("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL, t)
ds := &mockDataStore{
assets: map[fleet.MDMAssetName]fleet.MDMConfigAsset{}, // Empty - no cached token
@@ -363,7 +356,7 @@ func TestAuthentication(t *testing.T) {
})
t.Run("returns error when auth server fails", func(t *testing.T) {
os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "")
dev_mode.SetOverride("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "", t)
// Set up a mock auth server that fails
authServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -371,7 +364,7 @@ func TestAuthentication(t *testing.T) {
_, _ = w.Write([]byte(`{"error": "invalid license"}`))
}))
defer authServer.Close()
os.Setenv("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL, t)
ds := &mockDataStore{
assets: map[fleet.MDMAssetName]fleet.MDMConfigAsset{}, // Empty
@@ -389,7 +382,7 @@ func TestAuthentication(t *testing.T) {
})
t.Run("returns error when auth response has empty token", func(t *testing.T) {
os.Setenv("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "")
dev_mode.SetOverride("FLEET_DEV_VPP_METADATA_BEARER_TOKEN", "", t)
// Set up a mock auth server that returns empty token
authServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -397,7 +390,7 @@ func TestAuthentication(t *testing.T) {
_, _ = w.Write([]byte(`{"fleetServerSecret": ""}`))
}))
defer authServer.Close()
os.Setenv("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_PROXY_AUTH_URL", authServer.URL, t)
ds := &mockDataStore{
assets: map[fleet.MDMAssetName]fleet.MDMConfigAsset{},
@@ -492,7 +485,7 @@ func TestDoRetries(t *testing.T) {
})
start := time.Now()
req, err := http.NewRequest(http.MethodGet, os.Getenv("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL"), nil)
req, err := http.NewRequest(http.MethodGet, dev_mode.Env("FLEET_DEV_STOKEN_AUTHENTICATED_APPS_URL"), nil)
require.NoError(t, err)
err = do(req, func(forceRenew bool) (string, error) {
if forceRenew {
+2 -2
View File
@@ -36,9 +36,9 @@ import (
"encoding/base64"
"errors"
"fmt"
"os"
"strings"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/apple/rootcert"
"github.com/micromdm/plist"
@@ -171,7 +171,7 @@ func ParseMachineInfoFromPKCS7(buf []byte, verify bool) (*fleet.MDMAppleMachineI
//
// NOTE: most of this code was taken from micromdm.
func VerifyFromAppleIphoneDeviceCA(c *x509.Certificate) error {
if os.Getenv("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY") == "1" {
if dev_mode.Env("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY") == "1" {
return nil
}
+2 -2
View File
@@ -9,13 +9,13 @@ import (
"io"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
"github.com/cenkalti/backoff"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/apple/rootcert"
)
@@ -205,7 +205,7 @@ func doWithRetry(req *http.Request) (*http.Response, error) {
}
func getBaseURL() string {
devURL := os.Getenv("FLEET_DEV_GDMF_URL")
devURL := dev_mode.Env("FLEET_DEV_GDMF_URL")
if devURL != "" {
return devURL
}
+4 -3
View File
@@ -6,6 +6,7 @@ import (
"os"
"testing"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
@@ -24,7 +25,7 @@ func TestGetLatest(t *testing.T) {
require.NoError(t, err)
}))
defer srv.Close()
t.Setenv("FLEET_DEV_GDMF_URL", srv.URL)
dev_mode.SetOverride("FLEET_DEV_GDMF_URL", srv.URL, t)
// test the function
d := fleet.MDMAppleMachineInfo{
@@ -224,10 +225,10 @@ func TestRetries(t *testing.T) {
_, err := w.Write([]byte(`{"error": "bad request"}`))
require.NoError(t, err)
}))
os.Setenv("FLEET_DEV_GDMF_URL", srv.URL)
dev_mode.SetOverride("FLEET_DEV_GDMF_URL", srv.URL)
t.Cleanup(func() {
srv.Close()
os.Unsetenv("FLEET_DEV_GDMF_URL")
dev_mode.ClearOverride("FLEET_DEV_GDMF_URL")
})
latest, err := GetLatestOSVersion(fleet.MDMAppleMachineInfo{
+2 -2
View File
@@ -10,12 +10,12 @@ import (
"net"
"net/http"
"net/url"
"os"
"strconv"
"time"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/pkg/retry"
"github.com/fleetdm/fleet/v4/server/dev_mode"
)
// Asset is a product in the store.
@@ -362,7 +362,7 @@ func do[T any](req *http.Request, token string, dest *T) error {
}
func getBaseURL() string {
devURL := os.Getenv("FLEET_DEV_VPP_URL")
devURL := dev_mode.Env("FLEET_DEV_VPP_URL")
if devURL != "" {
return devURL
}
+4 -5
View File
@@ -6,18 +6,18 @@ import (
"io"
"net/http"
"net/http/httptest"
"os"
"sync/atomic"
"testing"
"time"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/stretchr/testify/require"
)
func setupFakeServer(t *testing.T, handler http.HandlerFunc) {
server := httptest.NewServer(handler)
os.Setenv("FLEET_DEV_VPP_URL", server.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", server.URL, t)
t.Cleanup(server.Close)
}
@@ -356,7 +356,7 @@ func TestDoRetryAfter(t *testing.T) {
})
start := time.Now()
req, err := http.NewRequest(http.MethodGet, os.Getenv("FLEET_DEV_VPP_URL"), nil)
req, err := http.NewRequest(http.MethodGet, dev_mode.Env("FLEET_DEV_VPP_URL"), nil)
require.NoError(t, err)
err = do[any](req, "test-token", nil)
require.NoError(t, err)
@@ -368,13 +368,12 @@ func TestDoRetryAfter(t *testing.T) {
func TestGetBaseURL(t *testing.T) {
t.Run("Default URL", func(t *testing.T) {
os.Setenv("FLEET_DEV_VPP_URL", "")
require.Equal(t, "https://vpp.itunes.apple.com/mdm/v2", getBaseURL())
})
t.Run("Custom URL", func(t *testing.T) {
customURL := "http://localhost:8000"
os.Setenv("FLEET_DEV_VPP_URL", customURL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", customURL, t)
require.Equal(t, customURL, getBaseURL())
})
}
+3 -3
View File
@@ -7,12 +7,12 @@ import (
"fmt"
"io"
"net/http"
"os"
"time"
ma "github.com/fleetdm/fleet/v4/ee/maintained-apps"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
kitlog "github.com/go-kit/log"
)
@@ -45,7 +45,7 @@ func Refresh(ctx context.Context, ds fleet.Datastore, logger kitlog.Logger) erro
func FetchAppsList(ctx context.Context) (*AppsList, error) {
httpClient := fleethttp.NewClient(fleethttp.WithTimeout(10 * time.Second))
baseURL := fmaOutputsBase
if baseFromEnvVar := os.Getenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL"); baseFromEnvVar != "" {
if baseFromEnvVar := dev_mode.Env("FLEET_DEV_MAINTAINED_APPS_BASE_URL"); baseFromEnvVar != "" {
baseURL = baseFromEnvVar
}
@@ -119,7 +119,7 @@ func upsertMaintainedApps(ctx context.Context, appsList *AppsList, ds fleet.Data
func Hydrate(ctx context.Context, app *fleet.MaintainedApp) (*fleet.MaintainedApp, error) {
httpClient := fleethttp.NewClient(fleethttp.WithTimeout(10 * time.Second))
baseURL := fmaOutputsBase
if baseFromEnvVar := os.Getenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL"); baseFromEnvVar != "" {
if baseFromEnvVar := dev_mode.Env("FLEET_DEV_MAINTAINED_APPS_BASE_URL"); baseFromEnvVar != "" {
baseURL = baseFromEnvVar
}
+5 -4
View File
@@ -10,6 +10,7 @@ import (
"runtime"
"testing"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/go-kit/log"
"github.com/stretchr/testify/require"
@@ -41,8 +42,8 @@ func SyncApps(t *testing.T, ds fleet.Datastore) []fleet.MaintainedApp {
// not using t.Setenv because we want the env var to be unset on return of
// this call
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL)
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL)
defer dev_mode.ClearOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
err := Refresh(context.Background(), ds, log.NewNopLogger())
require.NoError(t, err)
@@ -97,8 +98,8 @@ func SyncAndRemoveApps(t *testing.T, ds fleet.Datastore) {
// not using t.Setenv because we want the env var to be unset on return of
// this call
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL)
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL)
defer dev_mode.ClearOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
err = Refresh(context.Background(), ds, log.NewNopLogger())
require.NoError(t, err)
+2 -2
View File
@@ -13,7 +13,6 @@ import (
"errors"
"fmt"
"math/big"
"os"
"strconv"
"strings"
"time"
@@ -21,6 +20,7 @@ import (
"github.com/MicahParks/jwkset"
"github.com/fleetdm/fleet/v4/server"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/cryptoutil"
"github.com/golang-jwt/jwt/v4"
@@ -258,7 +258,7 @@ func GetAzureAuthTokenClaims(ctx context.Context, tokenStr string) (AzureData, e
// Parse JWT token
jwksURI := "https://login.microsoftonline.com/common/discovery/v2.0/keys"
var token *jwt.Token
FLEET_DEV_AZURE_JWT_JWKS_URI := os.Getenv("FLEET_DEV_AZURE_JWT_JWKS_URI")
FLEET_DEV_AZURE_JWT_JWKS_URI := dev_mode.Env("FLEET_DEV_AZURE_JWT_JWKS_URI")
if FLEET_DEV_AZURE_JWT_JWKS_URI != "" {
jwksURI = FLEET_DEV_AZURE_JWT_JWKS_URI
}
+2 -1
View File
@@ -35,6 +35,7 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/datastore/redis/redistest"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
fleetmdm "github.com/fleetdm/fleet/v4/server/mdm"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
@@ -5121,7 +5122,7 @@ func TestCheckMDMAppleEnrollmentWithMinimumOSVersion(t *testing.T) {
require.NoError(t, err)
}))
defer gdmf.Close()
t.Setenv("FLEET_DEV_GDMF_URL", gdmf.URL)
dev_mode.SetOverride("FLEET_DEV_GDMF_URL", gdmf.URL, t)
latestMacOSVersion := "14.6.1"
latestMacOSBuild := "23G93"
+2 -2
View File
@@ -9,13 +9,13 @@ import (
"fmt"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"text/template"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/contexts/logging"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/google/uuid"
)
@@ -367,7 +367,7 @@ func (svc *Service) ConditionalAccessGetIdPAppleProfile(ctx context.Context) (pr
challenge := secrets[0].Secret
// Get mTLS URL using ConditionalAccessIdPSSOURL
mtlsURL, err := appConfig.ConditionalAccessIdPSSOURL(os.Getenv)
mtlsURL, err := appConfig.ConditionalAccessIdPSSOURL(dev_mode.Env)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "failed to get mTLS URL")
}
@@ -45,6 +45,7 @@ import (
"github.com/fleetdm/fleet/v4/server/datastore/filesystem"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/datastore/redis/redistest"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/live_query/live_query_mock"
"github.com/fleetdm/fleet/v4/server/mdm"
@@ -18834,8 +18835,8 @@ func (s *integrationEnterpriseTestSuite) TestMaintainedApps() {
require.NoError(t, err)
}))
t.Cleanup(manifestServer.Close)
os.Setenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
defer os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", manifestServer.URL)
defer dev_mode.ClearOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
// Create a team
var newTeamResp teamResponse
@@ -19028,9 +19029,9 @@ func (s *integrationEnterpriseTestSuite) TestMaintainedApps() {
require.Contains(t, extractServerErrorText(r.Body), "mismatch in maintained app SHA256 hash")
// Should timeout
os.Setenv("FLEET_DEV_MAINTAINED_APPS_INSTALLER_TIMEOUT", "1s")
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_INSTALLER_TIMEOUT", "1s")
r = s.Do("POST", "/api/latest/fleet/software/fleet_maintained_apps", &addFleetMaintainedAppRequest{AppID: 3}, http.StatusGatewayTimeout)
os.Unsetenv("FLEET_DEV_MAINTAINED_APPS_INSTALLER_TIMEOUT")
dev_mode.ClearOverride("FLEET_DEV_MAINTAINED_APPS_INSTALLER_TIMEOUT")
require.Contains(t, extractServerErrorText(r.Body), "Couldn't add. Request timeout. Please make sure your server and load balancer timeout is long enough.")
// Add a maintained app to no team
@@ -13,6 +13,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/mdm/mdmtest"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/android"
android_service "github.com/fleetdm/fleet/v4/server/mdm/android/service"
@@ -744,7 +745,7 @@ func (s *integrationMDMTestSuite) TestSetupExperienceVPPInstallError() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -1863,7 +1864,7 @@ func (s *integrationMDMTestSuite) TestSetupExperienceVPPCRUD() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -2090,7 +2091,7 @@ func (s *integrationMDMTestSuite) TestSetupExperienceIOSAndIPadOS() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -3009,7 +3010,7 @@ func (s *integrationMDMTestSuite) TestSetupExperienceFlowWithRequiredSoftwareVPP
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
+15 -14
View File
@@ -37,6 +37,7 @@ import (
"github.com/MicahParks/jwkset"
"github.com/davecgh/go-spew/spew"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/mdm/android"
android_mock "github.com/fleetdm/fleet/v4/server/mdm/android/mock"
android_service "github.com/fleetdm/fleet/v4/server/mdm/android/service"
@@ -11722,7 +11723,7 @@ func (s *integrationMDMTestSuite) TestBatchAssociateAppStoreApps() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var vppRes uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &vppRes)
@@ -12578,13 +12579,13 @@ func (s *integrationMDMTestSuite) TestVPPApps() {
s.setSkipWorkerJobs(t)
// Invalid token
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL+"?invalidToken")
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL+"?invalidToken", t)
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte("foobar"), http.StatusUnprocessableEntity, "Invalid token. Please provide a valid content token from Apple Business Manager.", nil)
// Attempt to renew an invalid (nonexistent) token, should fail
s.uploadDataViaFormWithVerb("/api/latest/fleet/vpp_tokens/999/renew", "PATCH", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte("foobar"))), http.StatusUnprocessableEntity, "Invalid token. Please provide a valid content token from Apple Business Manager.", nil)
// Simulate a server error from the Apple API
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL+"?serverError")
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL+"?serverError", t)
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte("foobar"), http.StatusInternalServerError, "Apple VPP endpoint returned error: Internal server error (error number: 9603)", nil)
// Valid token
@@ -12594,7 +12595,7 @@ func (s *integrationMDMTestSuite) TestVPPApps() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -13852,7 +13853,7 @@ func (s *integrationMDMTestSuite) TestNoTeamVPPAppIcons() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -13945,7 +13946,7 @@ func (s *integrationMDMTestSuite) TestVPPAppPolicyAutomation() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -14828,7 +14829,7 @@ func (s *integrationMDMTestSuite) TestOTAEnrollment() {
})
t.Run("if invalid device signature", func(t *testing.T) {
t.Setenv("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY", "1")
dev_mode.SetOverride("FLEET_DEV_MDM_APPLE_DISABLE_DEVICE_INFO_CERT_VERIFY", "1", t)
httpResp := s.DoRawNoAuth("POST", "/api/latest/fleet/ota_enrollment?enroll_secret=foo", signedReqBody, http.StatusForbidden)
errMsg := extractServerErrorText(httpResp.Body)
require.Contains(t, errMsg, "Couldn't install the profile. Invalid enroll secret. Please contact your IT admin.")
@@ -17551,7 +17552,7 @@ func (s *integrationMDMTestSuite) TestVPPPolicyAutomationLabelScopingRetrigger()
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -17809,7 +17810,7 @@ func (s *integrationMDMTestSuite) TestRefreshVPPAppVersions() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -17927,7 +17928,7 @@ func (s *integrationMDMTestSuite) TestRefreshVPPAppVersionsForAllPlatforms() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -18075,7 +18076,7 @@ func (s *integrationMDMTestSuite) TestUpcomingActivitiesTurnMDMOff() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -18609,7 +18610,7 @@ func (s *integrationMDMTestSuite) TestCancelUpcomingActivity() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -19098,7 +19099,7 @@ func (s *integrationMDMTestSuite) TestSoftwareCategories() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -20240,7 +20241,7 @@ func (s *integrationMDMTestSuite) TestTeamLabelsAssociationsCheck() {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
@@ -15,6 +15,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/mdm/mdmtest"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/apple/vpp"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
@@ -34,7 +35,7 @@ func (s *integrationMDMTestSuite) setVPPTokenForTeam(teamID uint) {
expTime := time.Now().Add(200 * time.Hour).UTC().Round(time.Second)
expDate := expTime.Format(fleet.VPPTimeFormat)
tokenJSON := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, expDate, token, orgName)
t.Setenv("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL)
dev_mode.SetOverride("FLEET_DEV_VPP_URL", s.appleVPPConfigSrv.URL, t)
var validToken uploadVPPTokenResponse
s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSON))), http.StatusAccepted, "", &validToken)
+4 -1
View File
@@ -9,6 +9,7 @@ import (
"slices"
"strings"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/go-json-experiment/json"
"github.com/go-json-experiment/json/jsontext"
"google.golang.org/api/androidmanagement/v1"
@@ -17,7 +18,7 @@ import (
// Required env vars:
var (
androidServiceCredentials = os.Getenv("FLEET_DEV_ANDROID_GOOGLE_SERVICE_CREDENTIALS")
androidServiceCredentials string
androidProjectID string
)
@@ -46,6 +47,8 @@ var commands = []string{
}
func main() {
dev_mode.IsEnabled = true
androidServiceCredentials = dev_mode.Env("FLEET_DEV_ANDROID_GOOGLE_SERVICE_CREDENTIALS")
if androidServiceCredentials == "" {
log.Fatal("FLEET_DEV_ANDROID_GOOGLE_SERVICE_CREDENTIALS must be set")
}