mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
Bootstrapping Android app (#36233)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #36202 Updated how Android agent starts. See README updates. # Checklist for submitter ## 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** * Periodic configuration check scheduled every 15 minutes in the Android agent * Improved Android management notification handling and app-role support * **Documentation** * Updated Android MDM deployment guide with SHA256 fingerprint instructions and build configuration snippets * **Chores** * Added WorkManager and AMAPI SDK for Android; updated Android/Go tooling and library versions * **Tests** * Added unit test coverage for the periodic config worker <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
287710b1c5
commit
61c51672e4
15 changed files with 259 additions and 81 deletions
11
.github/workflows/test-android.yml
vendored
11
.github/workflows/test-android.yml
vendored
|
|
@ -123,6 +123,17 @@ jobs:
|
|||
working-directory: android
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Free up disk space
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
||||
with:
|
||||
android: false
|
||||
dotnet: true
|
||||
haskell: true
|
||||
swap-storage: true
|
||||
large-packages: true
|
||||
tool-cache: false
|
||||
docker-images: false
|
||||
|
||||
- name: Enable KVM
|
||||
run: |
|
||||
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
- [Requirements](#requirements)
|
||||
- [Building the project](#building-the-project)
|
||||
- [Deploying via Android MDM](#deploying-via-android-mdm-development)
|
||||
- [How the app starts](#how-the-app-starts)
|
||||
- [Running tests](#running-tests)
|
||||
- [Code quality](#code-quality)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
|
@ -94,14 +95,28 @@ ls "$(grep sdk.dir local.properties | cut -d= -f2)/build-tools/"
|
|||
jarsigner -verify app/build/outputs/bundle/release/app-release.aab
|
||||
```
|
||||
|
||||
|
||||
### Getting the SHA256 fingerprint
|
||||
|
||||
The SHA256 fingerprint is required for MDM deployment. You can get it from your keystore.
|
||||
|
||||
```bash
|
||||
keytool -list -v -keystore keystore.jks -alias fleet-android
|
||||
# Grab SHA256
|
||||
echo <SHA256> | xxd -r -p | base64
|
||||
```
|
||||
|
||||
Copy the fingerprint for use in `FLEET_DEV_ANDROID_AGENT_SHA256`
|
||||
|
||||
## Deploying via Android MDM (development)
|
||||
|
||||
This feature is behind the feature flag `FLEET_DEV_ANDROID_AGENT_PACKAGE`. Requires `FLEET_DEV_ANDROID_GOOGLE_SERVICE_CREDENTIALS` to be set in your workarea.
|
||||
This feature is behind the feature flag `FLEET_DEV_ANDROID_AGENT_PACKAGE`. Requires `FLEET_DEV_ANDROID_GOOGLE_SERVICE_CREDENTIALS` to be set in your workarea to get the Google Play URL.
|
||||
|
||||
1. **Set the feature flag on your Fleet server:**
|
||||
1. **Set these env vars on your Fleet server:**
|
||||
|
||||
```bash
|
||||
export FLEET_DEV_ANDROID_AGENT_PACKAGE=com.fleetdm.agent.private.<yourname>
|
||||
export FLEET_DEV_ANDROID_AGENT_SHA256=<SHA256 fingerprint>
|
||||
```
|
||||
|
||||
2. **Change the `applicationId` in `app/build.gradle.kts`:**
|
||||
|
|
@ -130,6 +145,33 @@ go run tools/android/android.go --command enterprises.webTokens.create --enterpr
|
|||
|
||||
The agent should start installing shortly. Check Google Play in your Work profile. If it shows as pending, try restarting the device.
|
||||
|
||||
## How the app starts
|
||||
|
||||
The Fleet Android agent is designed to run automatically without user interaction. The app starts in three scenarios:
|
||||
|
||||
### 1. On installation (COMPANION_APP role)
|
||||
|
||||
When the app is installed via MDM, Android Device Policy assigns it the `COMPANION_APP` role. This triggers `RoleNotificationReceiverService`, which starts the app process and runs `AgentApplication.onCreate()`.
|
||||
|
||||
### 2. On device boot
|
||||
|
||||
When the device boots, `BootReceiver` receives the `ACTION_BOOT_COMPLETED` broadcast and starts the app process, triggering `AgentApplication.onCreate()`.
|
||||
|
||||
### 3. Periodically every 15 minutes
|
||||
|
||||
`AgentApplication.onCreate()` schedules a `ConfigCheckWorker` to run every 15 minutes using WorkManager. This ensures the app wakes up periodically even if the process is killed.
|
||||
|
||||
**Note:** WorkManager ensures reliable background execution. The work persists across device reboots and process death.
|
||||
|
||||
### Why not ACTION_APPLICATION_RESTRICTIONS_CHANGED?
|
||||
|
||||
We don't use `ACTION_APPLICATION_RESTRICTIONS_CHANGED` to detect MDM config changes because:
|
||||
|
||||
1. This broadcast can only be registered dynamically (not in the manifest)
|
||||
2. On Android 14+, [context-registered broadcasts are queued when the app is in cached state](https://developer.android.com/about/versions/14/behavior-changes-all#pending-broadcasts-queued)
|
||||
|
||||
This means the broadcast won't wake the app immediately when configs change if the app is in the background. WorkManager polling every 15 minutes is the reliable solution for detecting config changes.
|
||||
|
||||
### Full build with tests
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -101,7 +101,11 @@ dependencies {
|
|||
implementation(libs.androidx.compose.ui.graphics)
|
||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||
implementation(libs.androidx.compose.material3)
|
||||
implementation(libs.androidx.work.runtime.ktx)
|
||||
implementation(libs.amapi.sdk)
|
||||
testImplementation(libs.junit)
|
||||
testImplementation(libs.androidx.work.testing)
|
||||
testImplementation(libs.robolectric)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- Package visibility for Android Device Policy (required for targetSdk 30+) -->
|
||||
<!-- Source: https://developers.google.com/android/management/sdk-integration#add_queries -->
|
||||
<queries>
|
||||
<package android:name="com.google.android.apps.work.clouddpc" />
|
||||
</queries>
|
||||
|
||||
<!-- REQUIRED for downloading certificates from remote server -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
|
|
@ -9,6 +15,7 @@
|
|||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<application
|
||||
android:name=".AgentApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
|
|
@ -38,14 +45,15 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- ACTION_APPLICATION_RESTRICTIONS_CHANGED Receiver -->
|
||||
<receiver
|
||||
android:name=".RestrictionsReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.APPLICATION_RESTRICTIONS_CHANGED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- AMAPI NotificationReceiverService for COMPANION_APP role -->
|
||||
<service
|
||||
android:name=".RoleNotificationReceiverService"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedService">
|
||||
<meta-data
|
||||
android:name="com.google.android.managementapi.notification.NotificationReceiverService.SERVICE_APP_ROLES"
|
||||
android:value="" />
|
||||
</service>
|
||||
|
||||
<!-- Service Declaration -->
|
||||
<service
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package com.fleetdm.agent
|
||||
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Custom Application class for Fleet Agent.
|
||||
* Runs when the app process starts (triggered by broadcasts, not by user).
|
||||
*/
|
||||
class AgentApplication : Application() {
|
||||
companion object {
|
||||
private const val TAG = "fleet-app"
|
||||
private const val CONFIG_CHECK_WORK_NAME = "config_check_periodic"
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Log.i(TAG, "Fleet agent process started")
|
||||
schedulePeriodicConfigCheck()
|
||||
}
|
||||
|
||||
private fun schedulePeriodicConfigCheck() {
|
||||
val workRequest =
|
||||
PeriodicWorkRequestBuilder<ConfigCheckWorker>(
|
||||
15, // 15 is the minimum
|
||||
TimeUnit.MINUTES,
|
||||
).build()
|
||||
|
||||
WorkManager
|
||||
.getInstance(this)
|
||||
.enqueueUniquePeriodicWork(
|
||||
CONFIG_CHECK_WORK_NAME,
|
||||
ExistingPeriodicWorkPolicy.KEEP,
|
||||
workRequest,
|
||||
)
|
||||
|
||||
Log.i(TAG, "Scheduled periodic config check every 15 minutes")
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,9 @@ import android.content.Intent
|
|||
import android.util.Log
|
||||
|
||||
class BootReceiver : BroadcastReceiver() {
|
||||
private val TAG = "CertCompanionBoot"
|
||||
companion object {
|
||||
private const val TAG = "fleet-boot"
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
if (intent?.action == Intent.ACTION_BOOT_COMPLETED) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.fleetdm.agent
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
|
||||
/**
|
||||
* WorkManager worker that periodically checks managed configurations.
|
||||
*/
|
||||
class ConfigCheckWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
|
||||
companion object {
|
||||
private const val TAG = "fleet-worker"
|
||||
}
|
||||
|
||||
override fun doWork(): Result {
|
||||
Log.i(TAG, "Periodic config check triggered")
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package com.fleetdm.agent
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
|
||||
class RestrictionsReceiver : BroadcastReceiver() {
|
||||
private val TAG = "CertCompanionRestrict"
|
||||
private val CERT_DATA_KEY = "certificate_data"
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
if (intent?.action == Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED) {
|
||||
Log.i(TAG, "Application restrictions changed. Checking for new certificate data.")
|
||||
|
||||
// Ensure context is not null before proceeding
|
||||
context?.let {
|
||||
// 1. Fetch the Managed Configuration (Application Restrictions)
|
||||
val restrictionsManager = context.getSystemService(Context.RESTRICTIONS_SERVICE) as android.content.RestrictionsManager
|
||||
val appRestrictions = restrictionsManager.applicationRestrictions
|
||||
|
||||
val certData = appRestrictions.getString(CERT_DATA_KEY)
|
||||
|
||||
if (!certData.isNullOrEmpty()) {
|
||||
Log.d(TAG, "New certificate data found in restrictions.")
|
||||
|
||||
// 2. Start the service to handle the installation asynchronously
|
||||
val serviceIntent = Intent(it, CertificateService::class.java).apply {
|
||||
putExtra("CERT_DATA", certData)
|
||||
}
|
||||
it.startService(serviceIntent)
|
||||
} else {
|
||||
Log.d(TAG, "No relevant certificate data found for key '$CERT_DATA_KEY'.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.fleetdm.agent
|
||||
|
||||
import android.util.Log
|
||||
import com.google.android.managementapi.approles.AppRolesListener
|
||||
import com.google.android.managementapi.approles.model.AppRolesSetRequest
|
||||
import com.google.android.managementapi.approles.model.AppRolesSetResponse
|
||||
import com.google.android.managementapi.notification.NotificationReceiverService
|
||||
|
||||
/**
|
||||
* Service to receive notifications from Android Device Policy (ADP) for COMPANION_APP role.
|
||||
* We need the service to force the app to run right after it is installed via MDM.
|
||||
*/
|
||||
class RoleNotificationReceiverService : NotificationReceiverService() {
|
||||
companion object {
|
||||
private const val TAG = "fleet-notification"
|
||||
}
|
||||
|
||||
override fun getAppRolesListener(): AppRolesListener = object : AppRolesListener {
|
||||
override fun onAppRolesSet(request: AppRolesSetRequest): AppRolesSetResponse {
|
||||
Log.i(TAG, "App roles set by Android Device Policy")
|
||||
return AppRolesSetResponse.getDefaultInstance()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.fleetdm.agent
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.ListenableWorker
|
||||
import androidx.work.testing.TestListenableWorkerBuilder
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.RuntimeEnvironment
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class ConfigCheckWorkerTest {
|
||||
private lateinit var context: Context
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context = RuntimeEnvironment.getApplication()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoWork() {
|
||||
val worker =
|
||||
TestListenableWorkerBuilder<ConfigCheckWorker>(context)
|
||||
.build()
|
||||
|
||||
// Execute the worker
|
||||
val result = worker.doWork()
|
||||
assertEquals(ListenableWorker.Result.success(), result)
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,9 @@ activityCompose = "1.12.0"
|
|||
composeBom = "2025.11.01"
|
||||
spotless = "8.1.0"
|
||||
detekt = "1.23.8"
|
||||
workManager = "2.11.0"
|
||||
amapi = "1.7.0"
|
||||
robolectric = "4.16"
|
||||
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
|
|
@ -26,6 +29,10 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u
|
|||
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||
androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "workManager" }
|
||||
androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "workManager" }
|
||||
amapi-sdk = { group = "com.google.android.libraries.enterprise.amapi", name = "amapi", version.ref = "amapi" }
|
||||
robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
|
|
|||
20
go.mod
20
go.mod
|
|
@ -153,14 +153,14 @@ require (
|
|||
golang.org/x/image v0.18.0
|
||||
golang.org/x/mod v0.29.0
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
golang.org/x/oauth2 v0.33.0
|
||||
golang.org/x/sync v0.18.0
|
||||
golang.org/x/sys v0.38.0
|
||||
golang.org/x/term v0.37.0
|
||||
golang.org/x/text v0.31.0
|
||||
golang.org/x/tools v0.38.0
|
||||
google.golang.org/api v0.249.0
|
||||
google.golang.org/grpc v1.75.0
|
||||
google.golang.org/api v0.256.0
|
||||
google.golang.org/grpc v1.76.0
|
||||
gopkg.in/guregu/null.v3 v3.5.0
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
|
|
@ -171,9 +171,9 @@ require (
|
|||
|
||||
require (
|
||||
cloud.google.com/go v0.120.0 // indirect
|
||||
cloud.google.com/go/auth v0.16.5 // indirect
|
||||
cloud.google.com/go/auth v0.17.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.8.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
cloud.google.com/go/iam v1.5.2 // indirect
|
||||
cyphar.com/go-pathrs v0.2.1 // indirect
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
|
|
@ -255,7 +255,7 @@ require (
|
|||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/go-tpm-tools v0.4.5 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||
github.com/goreleaser/chglog v0.4.2 // indirect
|
||||
github.com/goreleaser/fileglob v1.3.0 // indirect
|
||||
|
|
@ -337,11 +337,11 @@ require (
|
|||
go.opentelemetry.io/otel/metric v1.38.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect
|
||||
google.golang.org/protobuf v1.36.8 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
|
|
|
|||
49
go.sum
49
go.sum
|
|
@ -1,12 +1,12 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
|
||||
cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q=
|
||||
cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
|
||||
cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
|
||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA=
|
||||
cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw=
|
||||
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
|
||||
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
|
||||
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
|
||||
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
|
||||
cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk=
|
||||
|
|
@ -206,6 +206,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls=
|
||||
github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
|
||||
|
|
@ -303,7 +305,12 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM
|
|||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
||||
github.com/facebookincubator/flog v0.0.0-20190930132826-d2511d0ce33c h1:KqlxcP2nuOcMjudCvK0qME2K/aFBDH+xcvYv7HYQaYc=
|
||||
github.com/facebookincubator/flog v0.0.0-20190930132826-d2511d0ce33c/go.mod h1:QGzNH9ujQ2ZUr/CjDGZGWeDAVStrWNjHeEcjJL96Nuk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
|
|
@ -468,8 +475,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||
|
|
@ -705,6 +712,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0=
|
||||
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
|
|
@ -985,8 +994,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
|||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
|
||||
golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
@ -1059,8 +1068,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
|
|
@ -1081,8 +1090,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/api v0.249.0 h1:0VrsWAKzIZi058aeq+I86uIXbNhm9GxSHpbmZ92a38w=
|
||||
google.golang.org/api v0.249.0/go.mod h1:dGk9qyI0UYPwO/cjt2q06LG/EhUpwZGdAbYF14wHHrQ=
|
||||
google.golang.org/api v0.256.0 h1:u6Khm8+F9sxbCTYNoBHg6/Hwv0N/i+V94MvkOSor6oI=
|
||||
google.golang.org/api v0.256.0/go.mod h1:KIgPhksXADEKJlnEoRa9qAII4rXcy40vfI8HRqcU964=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
|
|
@ -1092,18 +1101,18 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
|||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b h1:ULiyYQ0FdsJhwwZUwbaXpZF5yUE3h+RA+gxvBu37ucc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:oDOGiMSXHL4sDTJvFvIB9nRQCGdLP1o/iVaqQK8zB+M=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 h1:tRPGkdGHuewF4UisLzzHHr1spKw92qLM98nIzxbC0wY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4=
|
||||
google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
|
||||
google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
|
@ -1115,8 +1124,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
|||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import (
|
|||
)
|
||||
|
||||
func TestGeneratePolicyFieldMask(t *testing.T) {
|
||||
const expectedMask = `accountTypesWithManagementDisabled,addUserDisabled,adjustVolumeDisabled,advancedSecurityOverrides,alwaysOnVpnPackage,androidDevicePolicyTracks,appAutoUpdatePolicy,appFunctions,assistContentPolicy,autoDateAndTimeZone,autoTimeRequired,blockApplicationsEnabled,bluetoothConfigDisabled,bluetoothContactSharingDisabled,bluetoothDisabled,cameraAccess,cameraDisabled,cellBroadcastsConfigDisabled,choosePrivateKeyRules,complianceRules,createWindowsDisabled,credentialProviderPolicyDefault,credentialsConfigDisabled,crossProfilePolicies,dataRoamingDisabled,debuggingFeaturesAllowed,defaultPermissionPolicy,deviceConnectivityManagement,deviceOwnerLockScreenInfo,deviceRadioState,displaySettings,encryptionPolicy,ensureVerifyAppsEnabled,enterpriseDisplayNameVisibility,factoryResetDisabled,frpAdminEmails,funDisabled,installAppsDisabled,installUnknownSourcesAllowed,keyguardDisabled,keyguardDisabledFeatures,kioskCustomLauncherEnabled,kioskCustomization,locationMode,longSupportMessage,maximumTimeToLock,microphoneAccess,minimumApiLevel,mobileNetworksConfigDisabled,modifyAccountsDisabled,mountPhysicalMediaDisabled,name,networkEscapeHatchEnabled,networkResetDisabled,oncCertificateProviders,openNetworkConfiguration,outgoingBeamDisabled,outgoingCallsDisabled,passwordPolicies,passwordRequirements,permissionGrants,permittedAccessibilityServices,permittedInputMethods,persistentPreferredActivities,personalUsagePolicies,playStoreMode,policyEnforcementRules,preferentialNetworkService,printingPolicy,privateKeySelectionEnabled,recommendedGlobalProxy,removeUserDisabled,safeBootDisabled,screenCaptureDisabled,setUserIconDisabled,setWallpaperDisabled,setupActions,shareLocationDisabled,shortSupportMessage,skipFirstUseHintsEnabled,smsDisabled,statusBarDisabled,statusReportingSettings,stayOnPluggedModes,systemUpdate,tetheringConfigDisabled,uninstallAppsDisabled,unmuteMicrophoneDisabled,usageLog,usbFileTransferDisabled,usbMassStorageEnabled,version,vpnConfigDisabled,wifiConfigDisabled,wifiConfigsLockdownEnabled,wipeDataFlags,workAccountSetupConfig`
|
||||
const expectedMask = `accountTypesWithManagementDisabled,addUserDisabled,adjustVolumeDisabled,advancedSecurityOverrides,alwaysOnVpnPackage,androidDevicePolicyTracks,appAutoUpdatePolicy,appFunctions,assistContentPolicy,autoDateAndTimeZone,autoTimeRequired,blockApplicationsEnabled,bluetoothConfigDisabled,bluetoothContactSharingDisabled,bluetoothDisabled,cameraAccess,cameraDisabled,cellBroadcastsConfigDisabled,choosePrivateKeyRules,complianceRules,createWindowsDisabled,credentialProviderPolicyDefault,credentialsConfigDisabled,crossProfilePolicies,dataRoamingDisabled,debuggingFeaturesAllowed,defaultApplicationSettings,defaultPermissionPolicy,deviceConnectivityManagement,deviceOwnerLockScreenInfo,deviceRadioState,displaySettings,encryptionPolicy,ensureVerifyAppsEnabled,enterpriseDisplayNameVisibility,factoryResetDisabled,frpAdminEmails,funDisabled,installAppsDisabled,installUnknownSourcesAllowed,keyguardDisabled,keyguardDisabledFeatures,kioskCustomLauncherEnabled,kioskCustomization,locationMode,longSupportMessage,maximumTimeToLock,microphoneAccess,minimumApiLevel,mobileNetworksConfigDisabled,modifyAccountsDisabled,mountPhysicalMediaDisabled,name,networkEscapeHatchEnabled,networkResetDisabled,oncCertificateProviders,openNetworkConfiguration,outgoingBeamDisabled,outgoingCallsDisabled,passwordPolicies,passwordRequirements,permissionGrants,permittedAccessibilityServices,permittedInputMethods,persistentPreferredActivities,personalUsagePolicies,playStoreMode,policyEnforcementRules,preferentialNetworkService,printingPolicy,privateKeySelectionEnabled,recommendedGlobalProxy,removeUserDisabled,safeBootDisabled,screenCaptureDisabled,setUserIconDisabled,setWallpaperDisabled,setupActions,shareLocationDisabled,shortSupportMessage,skipFirstUseHintsEnabled,smsDisabled,statusBarDisabled,statusReportingSettings,stayOnPluggedModes,systemUpdate,tetheringConfigDisabled,uninstallAppsDisabled,unmuteMicrophoneDisabled,usageLog,usbFileTransferDisabled,usbMassStorageEnabled,version,vpnConfigDisabled,wifiConfigDisabled,wifiConfigsLockdownEnabled,wipeDataFlags,workAccountSetupConfig`
|
||||
mask := generatePolicyFieldMask()
|
||||
assert.NotContains(t, mask, "omitempty")
|
||||
assert.NotContains(t, mask, "applications")
|
||||
assert.Equal(t, mask, expectedMask)
|
||||
assert.Equal(t, expectedMask, mask)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -891,6 +891,10 @@ func (svc *Service) AddFleetAgentToAndroidPolicy(ctx context.Context, enterprise
|
|||
) error {
|
||||
var errs []error
|
||||
if packageName := os.Getenv("FLEET_DEV_ANDROID_AGENT_PACKAGE"); packageName != "" {
|
||||
sha256Fingerprint := os.Getenv("FLEET_DEV_ANDROID_AGENT_SHA256")
|
||||
if sha256Fingerprint == "" {
|
||||
return ctxerr.New(ctx, "FLEET_DEV_ANDROID_AGENT_SHA256 must be set when FLEET_DEV_ANDROID_AGENT_PACKAGE is set")
|
||||
}
|
||||
for uuid, managedConfig := range hostConfigs {
|
||||
policyName := fmt.Sprintf("%s/policies/%s", enterpriseName, uuid)
|
||||
|
||||
|
|
@ -907,6 +911,16 @@ func (svc *Service) AddFleetAgentToAndroidPolicy(ctx context.Context, enterprise
|
|||
DefaultPermissionPolicy: "GRANT",
|
||||
DelegatedScopes: []string{"CERT_INSTALL"},
|
||||
ManagedConfiguration: managedConfigJSON,
|
||||
SigningKeyCerts: []*androidmanagement.ApplicationSigningKeyCert{
|
||||
{
|
||||
SigningKeyCertFingerprintSha256: sha256Fingerprint,
|
||||
},
|
||||
},
|
||||
Roles: []*androidmanagement.Role{
|
||||
{
|
||||
RoleType: "COMPANION_APP",
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err = svc.androidAPIClient.EnterprisesPoliciesModifyPolicyApplications(ctx, policyName,
|
||||
[]*androidmanagement.ApplicationPolicy{fleetAgentApp})
|
||||
|
|
|
|||
Loading…
Reference in a new issue