Allow Microsoft conditional access on premium self-hosted (#49414)
Resolves #47699. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [X] Added/updated automated tests - [X] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Microsoft Entra Conditional Access is now supported for self-hosted Fleet Premium instances. * Conditional Access is available only on the Fleet Premium license tier. * **Changes** * Removed the Microsoft Compliance Partner API key configuration and updated the proxy behavior accordingly. * Removed the managed-cloud indicator from license/config responses and adjusted related UI rendering and gating. * **Tests / Maintenance** * Updated fixtures and automated tests to reflect the new licensing gates and API/proxy behavior (including updated failure codes). <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- Enabled Microsoft Entra conditional access for self-hosted Fleet Premium instances (previously available only on Fleet Cloud). The `microsoft_compliance_partner.proxy_api_key` server configuration has been removed; the feature is now gated on the Fleet Premium license tier.
|
||||
+15
-17
@@ -428,23 +428,21 @@ func runServeCmd(cmd *cobra.Command, configManager configpkg.Manager, debug, dev
|
||||
}
|
||||
})
|
||||
|
||||
var conditionalAccessMicrosoftProxy *conditional_access_microsoft_proxy.Proxy
|
||||
if config.MicrosoftCompliancePartner.IsSet() {
|
||||
var err error
|
||||
conditionalAccessMicrosoftProxy, err = conditional_access_microsoft_proxy.New(
|
||||
config.MicrosoftCompliancePartner.ProxyURI,
|
||||
config.MicrosoftCompliancePartner.ProxyAPIKey,
|
||||
func() (string, error) {
|
||||
appCfg, err := ds.AppConfig(ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to load appconfig: %w", err)
|
||||
}
|
||||
return appCfg.ServerSettings.ServerURL, nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
initFatal(err, "new microsoft compliance proxy")
|
||||
}
|
||||
// The Microsoft Compliance Partner proxy is available to all Fleet Premium
|
||||
// instances (including self-hosted). The feature itself is gated on the
|
||||
// license tier at the service layer.
|
||||
conditionalAccessMicrosoftProxy, err := conditional_access_microsoft_proxy.New(
|
||||
config.MicrosoftCompliancePartner.ProxyURI,
|
||||
func() (string, error) {
|
||||
appCfg, err := ds.AppConfig(ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to load appconfig: %w", err)
|
||||
}
|
||||
return appCfg.ServerSettings.ServerURL, nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
initFatal(err, "new microsoft compliance proxy")
|
||||
}
|
||||
|
||||
eh := errorstore.NewHandler(ctx, redisPool, logger, config.Logging.ErrorRetentionPeriod)
|
||||
|
||||
+1
-2
@@ -232,8 +232,7 @@
|
||||
},
|
||||
"license": {
|
||||
"tier": "free",
|
||||
"expiration": "0001-01-01T00:00:00Z",
|
||||
"managed_cloud": false
|
||||
"expiration": "0001-01-01T00:00:00Z"
|
||||
},
|
||||
"logging": {
|
||||
"debug": true,
|
||||
|
||||
@@ -120,7 +120,6 @@ spec:
|
||||
license:
|
||||
expiration: "0001-01-01T00:00:00Z"
|
||||
tier: free
|
||||
managed_cloud: false
|
||||
logging:
|
||||
debug: true
|
||||
json: false
|
||||
|
||||
@@ -88,6 +88,12 @@ func RunServerWithMockedDS(t *testing.T, opts ...*service.TestServerOpts) (*http
|
||||
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
|
||||
return &fleet.AppConfig{}, nil
|
||||
}
|
||||
// On Premium, AppConfig assembly reads the Microsoft conditional access
|
||||
// integration. Default to an empty (not set up) integration so tests that
|
||||
// don't care about it don't panic on a nil mock.
|
||||
ds.ConditionalAccessMicrosoftGetFunc = func(ctx context.Context) (*fleet.ConditionalAccessMicrosoftIntegration, error) {
|
||||
return &fleet.ConditionalAccessMicrosoftIntegration{}, nil
|
||||
}
|
||||
ds.NewGlobalPolicyFunc = func(ctx context.Context, authorID *uint, args fleet.PolicyPayload) (*fleet.Policy, error) {
|
||||
return &fleet.Policy{
|
||||
PolicyData: fleet.PolicyData{
|
||||
|
||||
@@ -72,7 +72,6 @@ export const DEFAULT_LICENSE_MOCK: ILicense = {
|
||||
device_count: 4,
|
||||
note: "",
|
||||
organization: "",
|
||||
managed_cloud: true,
|
||||
allow_disable_telemetry: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ const DEFAULT_LICENSE_MOCK = {
|
||||
expiration: "2050-01-01T00:00:00Z",
|
||||
note: "test license",
|
||||
organization: "test org",
|
||||
managed_cloud: false,
|
||||
allow_disable_telemetry: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ export interface ILicense {
|
||||
expiration: string;
|
||||
note: string;
|
||||
organization: string;
|
||||
// Whether the Fleet instance is managed by FleetDM
|
||||
managed_cloud: boolean;
|
||||
allow_disable_telemetry: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ describe("Integrations Page", () => {
|
||||
describe("Conditional access", () => {
|
||||
it("Does not render the conditional access sidenav for self-hosted Fleet instances", () => {
|
||||
const mockConfig = createMockConfig({
|
||||
license: { ...DEFAULT_LICENSE_MOCK, managed_cloud: false },
|
||||
license: { ...DEFAULT_LICENSE_MOCK },
|
||||
});
|
||||
|
||||
const render = createCustomRenderer({
|
||||
|
||||
@@ -249,9 +249,6 @@ const ConditionalAccess = () => {
|
||||
|
||||
const oktaConfigured = isOktaConditionalAccessConfigured(config);
|
||||
|
||||
// Check if this is a managed cloud deployment (Microsoft Entra requires proxy infrastructure)
|
||||
const isManagedCloud = config?.license?.managed_cloud || false;
|
||||
|
||||
// Check Entra configuration state
|
||||
// Note: entraPhase is intentionally included in the dependency array to allow
|
||||
// manual phase overrides (e.g., AwaitingOAuth) to persist until config changes
|
||||
@@ -490,7 +487,7 @@ const ConditionalAccess = () => {
|
||||
return (
|
||||
<div className={`${baseClass}__cards`}>
|
||||
{renderOktaContent()}
|
||||
{isManagedCloud && renderEntraContent()}
|
||||
{renderEntraContent()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+2
-3
@@ -57,7 +57,7 @@ const AutomationsModal = ({
|
||||
onExit,
|
||||
}: IAutomationsModalProps): JSX.Element | null => {
|
||||
const queryClient = useQueryClient();
|
||||
const { setConfig } = useContext(AppContext);
|
||||
const { setConfig, isPremiumTier } = useContext(AppContext);
|
||||
|
||||
const otherFormRef = useRef<
|
||||
IAutomationFormHandle<IOtherWorkflowsModalSubmit>
|
||||
@@ -104,8 +104,7 @@ const AutomationsModal = ({
|
||||
? globalConfig?.integrations.conditional_access_enabled
|
||||
: teamConfig?.integrations.conditional_access_enabled) ?? false;
|
||||
|
||||
const isManagedCloud = globalConfig?.license?.managed_cloud || false;
|
||||
const conditionalAccessProviderText = isManagedCloud
|
||||
const conditionalAccessProviderText = isPremiumTier
|
||||
? "Okta or Microsoft Entra"
|
||||
: "Okta";
|
||||
|
||||
|
||||
+1
-12
@@ -863,20 +863,11 @@ func (c ConditionalAccessConfig) Validate(initFatal func(err error, msg string))
|
||||
}
|
||||
|
||||
// MicrosoftCompliancePartnerConfig holds the server configuration for the "Conditional access" feature.
|
||||
// Currently only set on Cloud environments.
|
||||
type MicrosoftCompliancePartnerConfig struct {
|
||||
// ProxyAPIKey is a shared key required to use the Microsoft Compliance Partner proxy API (fleetdm.com).
|
||||
ProxyAPIKey string `yaml:"proxy_api_key"`
|
||||
// ProxyURI is the URI of the Microsoft Compliance Partner proxy (for development/testing).
|
||||
ProxyURI string `yaml:"proxy_uri"`
|
||||
}
|
||||
|
||||
// IsSet returns if the compliance partner configuration is set.
|
||||
// Currently only set on Cloud environments.
|
||||
func (m MicrosoftCompliancePartnerConfig) IsSet() bool {
|
||||
return m.ProxyAPIKey != ""
|
||||
}
|
||||
|
||||
type MDMConfig struct {
|
||||
AppleAPNsCert string `yaml:"apple_apns_cert"`
|
||||
AppleAPNsCertBytes string `yaml:"apple_apns_cert_bytes"`
|
||||
@@ -1830,7 +1821,6 @@ func (man Manager) addConfigs() {
|
||||
man.addConfigBool("partnerships.enable_secureframe", false, "Point transparency URL at Secureframe landing page")
|
||||
|
||||
// Microsoft Compliance Partner
|
||||
man.addConfigString("microsoft_compliance_partner.proxy_api_key", "", "Shared key required to use the Microsoft Compliance Partner proxy API")
|
||||
man.addConfigString("microsoft_compliance_partner.proxy_uri", "https://fleetdm.com", "URI of the Microsoft Compliance Partner proxy (for development/testing)")
|
||||
|
||||
man.addConfigBool("partnerships.enable_primo", false, "Disables the ability to manage multiple fleets in an instance, even in premium tier")
|
||||
@@ -2173,8 +2163,7 @@ func (man Manager) LoadConfig() FleetConfig {
|
||||
EnablePrimo: man.getConfigBool("partnerships.enable_primo"),
|
||||
},
|
||||
MicrosoftCompliancePartner: MicrosoftCompliancePartnerConfig{
|
||||
ProxyAPIKey: man.getConfigString("microsoft_compliance_partner.proxy_api_key"),
|
||||
ProxyURI: man.getConfigString("microsoft_compliance_partner.proxy_uri"),
|
||||
ProxyURI: man.getConfigString("microsoft_compliance_partner.proxy_uri"),
|
||||
},
|
||||
ConditionalAccess: ConditionalAccessConfig{
|
||||
CertSerialFormat: man.getConfigString("conditional_access.cert_serial_format"),
|
||||
|
||||
@@ -186,7 +186,7 @@ func (ds *Datastore) ShouldSendStatistics(ctx context.Context, frequency time.Du
|
||||
stats.ConditionalAccessBypassDisabled = !appConfig.ConditionalAccess.BypassEnabled()
|
||||
}
|
||||
|
||||
stats.EntraConditionalAccessConfigured, err = ds.entraConditionalAccessConfigured(ctx, config)
|
||||
stats.EntraConditionalAccessConfigured, err = ds.entraConditionalAccessConfigured(ctx)
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "entra conditional access configured")
|
||||
}
|
||||
@@ -325,9 +325,11 @@ func fleetMaintainedAppsInUseDB(ctx context.Context, db sqlx.QueryerContext) (ma
|
||||
return macOSApps, windowsApps, nil
|
||||
}
|
||||
|
||||
func (ds *Datastore) entraConditionalAccessConfigured(ctx context.Context, fleetConfig config.FleetConfig) (bool, error) {
|
||||
// Check if the needed server configuration for Conditional Access is set.
|
||||
if !fleetConfig.MicrosoftCompliancePartner.IsSet() {
|
||||
func (ds *Datastore) entraConditionalAccessConfigured(ctx context.Context) (bool, error) {
|
||||
// Conditional access is a Fleet Premium feature. Gate on the current license
|
||||
// tier so that an integration left over from a previous Premium license
|
||||
// (e.g. after a downgrade or expiry) isn't reported as configured.
|
||||
if !license.IsPremium(ctx) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -574,9 +574,6 @@ func testConditionalAccessStatistics(t *testing.T, ds *Datastore) {
|
||||
markStatisticsStale(t, ctx, ds)
|
||||
|
||||
// Test Entra conditional access: create the integration but without setup done
|
||||
fleetConfig.MicrosoftCompliancePartner = config.MicrosoftCompliancePartnerConfig{
|
||||
ProxyAPIKey: "test-key",
|
||||
}
|
||||
err = ds.ConditionalAccessMicrosoftCreateIntegration(ctx, "test-tenant", "test-secret")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -598,9 +595,10 @@ func testConditionalAccessStatistics(t *testing.T, ds *Datastore) {
|
||||
|
||||
markStatisticsStale(t, ctx, ds)
|
||||
|
||||
// Without the fleet config proxy key, should be false even with setup done
|
||||
fleetConfig.MicrosoftCompliancePartner = config.MicrosoftCompliancePartnerConfig{}
|
||||
stats, shouldSend, err = ds.ShouldSendStatistics(license.NewContext(ctx, premiumLicense), time.Millisecond, fleetConfig)
|
||||
// On Fleet Free (e.g. after a license downgrade/expiry) the leftover
|
||||
// integration row must not be reported as configured.
|
||||
freeLicense := &fleet.LicenseInfo{Tier: fleet.TierFree}
|
||||
stats, shouldSend, err = ds.ShouldSendStatistics(license.NewContext(ctx, freeLicense), time.Millisecond, fleetConfig)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, shouldSend)
|
||||
assert.False(t, stats.EntraConditionalAccessConfigured)
|
||||
|
||||
@@ -1932,9 +1932,6 @@ type LicenseInfo struct {
|
||||
Note string `json:"note,omitempty"`
|
||||
// AllowDisableTelemetry allows specific customers to not send analytics
|
||||
AllowDisableTelemetry bool `json:"allow_disable_telemetry,omitempty"`
|
||||
// ManagedCloud indicates whether this Fleet instance is a cloud instance.
|
||||
// Currently only used to display UI features only present on cloud instances.
|
||||
ManagedCloud bool `json:"managed_cloud"`
|
||||
}
|
||||
|
||||
func (l *LicenseInfo) IsPremium() bool {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/authz"
|
||||
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
|
||||
"github.com/fleetdm/fleet/v4/server/contexts/license"
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
)
|
||||
|
||||
@@ -40,8 +41,8 @@ func (svc *Service) ConditionalAccessMicrosoftCreateIntegration(ctx context.Cont
|
||||
return "", ctxerr.Wrap(ctx, err, "failed to authorize")
|
||||
}
|
||||
|
||||
if !svc.config.MicrosoftCompliancePartner.IsSet() {
|
||||
return "", &fleet.BadRequestError{Message: "microsoft conditional access configuration not set"}
|
||||
if lic, _ := license.FromContext(ctx); lic == nil || !lic.IsPremium() {
|
||||
return "", fleet.ErrMissingLicense
|
||||
}
|
||||
|
||||
// Load current integration, if any.
|
||||
@@ -116,8 +117,8 @@ func (svc *Service) ConditionalAccessMicrosoftConfirm(ctx context.Context) (conf
|
||||
return false, "", ctxerr.Wrap(ctx, err, "failed to authorize")
|
||||
}
|
||||
|
||||
if !svc.config.MicrosoftCompliancePartner.IsSet() {
|
||||
return false, "", &fleet.BadRequestError{Message: "microsoft conditional access configuration not set"}
|
||||
if lic, _ := license.FromContext(ctx); lic == nil || !lic.IsPremium() {
|
||||
return false, "", fleet.ErrMissingLicense
|
||||
}
|
||||
|
||||
// Load current integration.
|
||||
@@ -182,8 +183,8 @@ func (svc *Service) ConditionalAccessMicrosoftDelete(ctx context.Context) error
|
||||
return ctxerr.Wrap(ctx, err, "failed to authorize")
|
||||
}
|
||||
|
||||
if !svc.config.MicrosoftCompliancePartner.IsSet() {
|
||||
return &fleet.BadRequestError{Message: "microsoft conditional access configuration not set"}
|
||||
if lic, _ := license.FromContext(ctx); lic == nil || !lic.IsPremium() {
|
||||
return fleet.ErrMissingLicense
|
||||
}
|
||||
|
||||
// Load current integration.
|
||||
@@ -231,7 +232,7 @@ func (svc *Service) ConditionalAccessMicrosoftGet(ctx context.Context) (*fleet.C
|
||||
return nil, ctxerr.Wrap(ctx, err, "failed to authorize")
|
||||
}
|
||||
|
||||
if !svc.config.MicrosoftCompliancePartner.IsSet() {
|
||||
if lic, _ := license.FromContext(ctx); lic == nil || !lic.IsPremium() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
+3
-6
@@ -18,20 +18,18 @@ import (
|
||||
// Proxy holds functionality to send requests to Entra via Fleet's MS proxy.
|
||||
type Proxy struct {
|
||||
uri string
|
||||
apiKey string
|
||||
originGetter func() (string, error)
|
||||
|
||||
c *http.Client
|
||||
}
|
||||
|
||||
// New creates a Proxy that will use the given URI and API key.
|
||||
func New(uri string, apiKey string, originGetter func() (string, error)) (*Proxy, error) {
|
||||
// New creates a Proxy that will use the given URI.
|
||||
func New(uri string, originGetter func() (string, error)) (*Proxy, error) {
|
||||
if _, err := url.Parse(uri); err != nil {
|
||||
return nil, fmt.Errorf("parse uri: %w", err)
|
||||
}
|
||||
return &Proxy{
|
||||
uri: uri,
|
||||
apiKey: apiKey,
|
||||
uri: uri,
|
||||
|
||||
originGetter: originGetter,
|
||||
|
||||
@@ -339,7 +337,6 @@ func (p *Proxy) setHeaders(r *http.Request) error {
|
||||
if origin == "" {
|
||||
return fmt.Errorf("missing origin: %w", err)
|
||||
}
|
||||
r.Header.Add("MS-API-Key", p.apiKey)
|
||||
r.Header.Add("Origin", origin)
|
||||
return nil
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ func TestProxyStatusErrorCapturesBody(t *testing.T) {
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
p, err := New(srv.URL, "key", func() (string, error) { return "https://fleet.example.com", nil })
|
||||
p, err := New(srv.URL, func() (string, error) { return "https://fleet.example.com", nil })
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = p.SetComplianceStatus(t.Context(), "tenant", "secret", "device", "upn", true, "name", "macOS", "14.0", false, time.Now())
|
||||
@@ -48,7 +48,7 @@ func TestProxyStatusErrorCapturesBody(t *testing.T) {
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
p, err := New(srv.URL, "key", func() (string, error) { return "https://fleet.example.com", nil })
|
||||
p, err := New(srv.URL, func() (string, error) { return "https://fleet.example.com", nil })
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = p.SetComplianceStatus(t.Context(), "tenant", "secret", "device", "upn", true, "name", "macOS", "14.0", false, time.Now())
|
||||
|
||||
@@ -15883,24 +15883,19 @@ func (s *integrationTestSuite) TestHostReenrollWithSameHostRowRefetchOsquery() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *integrationTestSuite) TestConditionalAccessOnlyCloud() {
|
||||
t := s.T()
|
||||
|
||||
var resp appConfigResponse
|
||||
s.DoJSON("GET", "/api/latest/fleet/config", nil, http.StatusOK, &resp)
|
||||
require.False(t, resp.License.ManagedCloud)
|
||||
|
||||
// Microsoft compliance partner APIs should fail if the setting is not set (only set on Cloud).
|
||||
func (s *integrationTestSuite) TestConditionalAccessRequiresPremium() {
|
||||
// Microsoft compliance partner APIs should fail on Fleet Free (this suite
|
||||
// runs without a premium license).
|
||||
var r conditionalAccessMicrosoftCreateResponse
|
||||
s.DoJSON("POST", "/api/latest/fleet/conditional-access/microsoft", conditionalAccessMicrosoftCreateRequest{
|
||||
MicrosoftTenantID: "foobar",
|
||||
}, http.StatusBadRequest, &r)
|
||||
}, http.StatusPaymentRequired, &r)
|
||||
var c conditionalAccessMicrosoftConfirmResponse
|
||||
s.DoJSON("POST", "/api/latest/fleet/conditional-access/microsoft/confirm", conditionalAccessMicrosoftConfirmRequest{},
|
||||
http.StatusBadRequest, &c)
|
||||
http.StatusPaymentRequired, &c)
|
||||
var d conditionalAccessMicrosoftDeleteResponse
|
||||
s.DoJSON("POST", "/api/latest/fleet/conditional-access/microsoft/confirm", conditionalAccessMicrosoftConfirmRequest{},
|
||||
http.StatusBadRequest, &d)
|
||||
s.DoJSON("DELETE", "/api/latest/fleet/conditional-access/microsoft", nil,
|
||||
http.StatusPaymentRequired, &d)
|
||||
}
|
||||
|
||||
func (s *integrationTestSuite) TestUpdateHostCertificateTemplate() {
|
||||
|
||||
@@ -23545,10 +23545,7 @@ func (s *integrationEnterpriseTestSuite) TestConditionalAccessBasicSetup() {
|
||||
s.clearOktaConditionalAccess()
|
||||
})
|
||||
|
||||
// Test license.managed_cloud is set on Cloud environments.
|
||||
var acResp appConfigResponse
|
||||
s.DoJSON("GET", "/api/latest/fleet/config", nil, http.StatusOK, &acResp)
|
||||
require.True(t, acResp.License.ManagedCloud)
|
||||
|
||||
// Test global maintainer fails to create the integration.
|
||||
u := &fleet.User{
|
||||
|
||||
@@ -2622,8 +2622,10 @@ func (svc *Service) processScriptsForNewlyFailingPolicies(
|
||||
}
|
||||
|
||||
func (svc *Service) conditionalAccessConfiguredAndEnabledForTeam(ctx context.Context, hostTeamID *uint) (configured bool, enabledForTeam bool, err error) {
|
||||
// Check if the needed server configuration for Conditional Access is set.
|
||||
if !svc.config.MicrosoftCompliancePartner.IsSet() {
|
||||
// Conditional access is a Fleet Premium feature. Gate on the current license
|
||||
// tier so that an integration left over from a previous Premium license
|
||||
// (e.g. after a downgrade or expiry) doesn't keep the feature active.
|
||||
if !license.IsPremium(ctx) {
|
||||
return false, false, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -86,16 +86,9 @@ func (svc *Service) License(ctx context.Context) (*fleet.LicenseInfo, error) {
|
||||
}
|
||||
|
||||
licChecker, _ := license.FromContext(ctx)
|
||||
// Type assert to get the concrete type for modification and return
|
||||
// Type assert to get the concrete type to return.
|
||||
lic, _ := licChecker.(*fleet.LicenseInfo)
|
||||
|
||||
// Currently we use the presence of Microsoft Compliance Partner settings
|
||||
// (only configured in cloud instances) to determine if a Fleet instance
|
||||
// is a cloud managed instance.
|
||||
if lic != nil && svc.config.MicrosoftCompliancePartner.IsSet() {
|
||||
lic.ManagedCloud = true
|
||||
}
|
||||
|
||||
return lic, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -170,7 +170,9 @@ func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig conf
|
||||
}
|
||||
if len(opts) > 0 && opts[0].ConditionalAccessMicrosoftProxy != nil {
|
||||
conditionalAccessMicrosoftProxy = opts[0].ConditionalAccessMicrosoftProxy
|
||||
fleetConfig.MicrosoftCompliancePartner.ProxyAPIKey = "insecure" // setting this so the feature is "enabled".
|
||||
// The Conditional Access feature is gated on Fleet Premium; callers that
|
||||
// exercise it must provide a premium license via opts[0].License.
|
||||
require.True(t, lic.IsPremium(), "ConditionalAccessMicrosoftProxy requires a premium license via opts.License")
|
||||
}
|
||||
|
||||
if len(opts) > 0 && opts[0].AndroidModule != nil {
|
||||
|
||||
@@ -98,6 +98,15 @@ func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig conf
|
||||
if mockDS.ValidateReferencedCustomHostVitalsFunc == nil {
|
||||
mockDS.ValidateReferencedCustomHostVitalsFunc = func(ctx context.Context, documents []string) error { return nil }
|
||||
}
|
||||
// On Premium, AppConfig assembly and the osquery detail-query flow read the
|
||||
// Microsoft conditional access integration. Default to an empty (not set up)
|
||||
// integration so premium tests that don't care about it don't panic on a nil
|
||||
// mock. Tests that assert on it can override.
|
||||
if mockDS.ConditionalAccessMicrosoftGetFunc == nil {
|
||||
mockDS.ConditionalAccessMicrosoftGetFunc = func(ctx context.Context) (*fleet.ConditionalAccessMicrosoftIntegration, error) {
|
||||
return &fleet.ConditionalAccessMicrosoftIntegration{}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lic := &fleet.LicenseInfo{Tier: fleet.TierFree}
|
||||
@@ -224,7 +233,9 @@ func newTestServiceWithConfig(t *testing.T, ds fleet.Datastore, fleetConfig conf
|
||||
}
|
||||
if len(opts) > 0 && opts[0].ConditionalAccessMicrosoftProxy != nil {
|
||||
conditionalAccessMicrosoftProxy = opts[0].ConditionalAccessMicrosoftProxy
|
||||
fleetConfig.MicrosoftCompliancePartner.ProxyAPIKey = "insecure" // setting this so the feature is "enabled".
|
||||
// The Conditional Access feature is gated on Fleet Premium; callers that
|
||||
// exercise it must provide a premium license via opts[0].License.
|
||||
require.True(t, lic.IsPremium(), "ConditionalAccessMicrosoftProxy requires a premium license via opts.License")
|
||||
}
|
||||
|
||||
if len(opts) > 0 && opts[0].AndroidModule != nil {
|
||||
|
||||
Reference in New Issue
Block a user