diff --git a/CODEOWNERS b/CODEOWNERS index c35c5c9b87..24fd9caaf0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -138,12 +138,6 @@ go.mod @fleetdm/go ############################################################################################## #/.github/ISSUE_TEMPLATE @mikermcneil @sampfluger88 @lukeheath # Covered in custom.js See https://github.com/fleetdm/fleet/pull/18668 - -############################################################################################## -# 🌐 Fleet website -############################################################################################## -/website/.sailsrc @eashaw # Note: eashaw will not approve any PR that changes this file. This codeowner exists to make sure no changes are committed to the repo. - ############################################################################################## # 🌐 GitHub workflows ############################################################################################## diff --git a/website/.sailsrc b/website/.sailsrc index 469767ed23..f6f62e1f79 100644 --- a/website/.sailsrc +++ b/website/.sailsrc @@ -1,7 +1,8 @@ { "generators": { "modules": { - "landing-page": "./generators/landing-page" + "landing-page": "./generators/landing-page", + "gitops": "./generators/gitops" } }, "_generatedWith": { diff --git a/website/config/custom.js b/website/config/custom.js index 269afb485d..6b4e646b09 100644 --- a/website/config/custom.js +++ b/website/config/custom.js @@ -148,7 +148,8 @@ module.exports.custom = { 'website/config': 'eashaw', 'website/config/routes.js': 'eashaw',//Β« Website redirects and URLs 'website/scripts': 'eashaw', - 'website/package.json': 'eashaw', + 'website/package.json': 'eashaw',// Β« This is where new website dependencies get added + 'website/.sailsrc': 'eashaw', // Β«This gets changed automatically when docs are compiled, so it's easy to accidentally check in changes that shouldn't be checked in. // 🫧 Vulnerability dashboard 'ee/vulnerability-dashboard': 'eashaw',// (catch-all) diff --git a/website/generators/gitops/README.md b/website/generators/gitops/README.md new file mode 100644 index 0000000000..43f1a3fb6a --- /dev/null +++ b/website/generators/gitops/README.md @@ -0,0 +1,7 @@ +To test: + +`cd website/` + +Then: + +`rm -rf /tmp/it-and-security/ && sails generate gitops && mv it-and-security /tmp/it-and-security && subl /tmp/it-and-security/` \ No newline at end of file diff --git a/website/generators/gitops/index.js b/website/generators/gitops/index.js new file mode 100644 index 0000000000..654ad68456 --- /dev/null +++ b/website/generators/gitops/index.js @@ -0,0 +1,93 @@ +module.exports = { + + targets: { + + './it-and-security/README.md': { copy: './README.md.template' }, + './it-and-security/.github': { folder: {} }, + './it-and-security/.github/fleet-gitops': { folder: {} }, + './it-and-security/.github/fleet-gitops/action.yml': { copy: './github/fleet-gitops/action.yml.template' }, + './it-and-security/.github/fleet-gitops/gitops.sh': { copy: './github/fleet-gitops/gitops.sh.template' }, + './it-and-security/.github/workflows': { folder: {} }, + './it-and-security/.github/workflows/fleet-gitops-workflow.yml': { copy: './github/workflows/fleet-gitops-workflow.yml.template' }, + './it-and-security/.gitlab-ci.yml': { copy: './gitlab-ci.yml.template' }, + './it-and-security/.gitignore': { copy: './gitignore.template' }, + './it-and-security/default.yml': { copy: './default.yml.template' }, + './it-and-security/fleets/': { folder: {} }, + './it-and-security/fleets/workstations.yml': { copy: './fleets/workstations.yml.template' }, + './it-and-security/fleets/personal-mobile-devices.yml': { copy: './fleets/personal-mobile-devices.yml.template' }, + './it-and-security/labels/': { folder: {} }, + './it-and-security/labels/apple-silicon-macos-hosts.yml': { copy: './labels/apple-silicon-macos-hosts.yml.template' }, + './it-and-security/labels/x86-based-windows-hosts.yml': { copy: './labels/x86-based-windows-hosts.yml.template' }, + './it-and-security/labels/arm-based-windows-hosts.yml': { copy: './labels/arm-based-windows-hosts.yml.template' }, + './it-and-security/labels/debian-based-linux-hosts.yml': { copy: './labels/debian-based-linux-hosts.yml.template' }, + './it-and-security/platforms/': { folder: {} }, + './it-and-security/platforms/linux': { folder: {} }, + './it-and-security/platforms/linux/policies/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/linux/reports/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/linux/scripts/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/linux/software/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/windows': { folder: {} }, + './it-and-security/platforms/windows/configuration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/windows/policies/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/windows/reports/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/windows/scripts/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/windows/software/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos': { folder: {} }, + './it-and-security/platforms/macos/configuration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos/declaration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos/enrollment-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos/enrollment-profiles/automatic-enrollment.dep.json': { copy: './platforms/macos/enrollment-profiles/automatic-enrollment.dep.json.template' }, + './it-and-security/platforms/macos/commands/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos/policies/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos/policies/all-software-updates-installed.yml': { copy: './platforms/macos/policies/all-software-updates-installed.yml' }, + './it-and-security/platforms/macos/reports/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos/scripts/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/macos/software/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/ios': { folder: {} }, + './it-and-security/platforms/ios/configuration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/ios/declaration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/ipados': { folder: {} }, + './it-and-security/platforms/ipados/configuration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/ipados/declaration-profiles/.gitkeep': { copy: './gitkeep.template' }, + // './it-and-security/platforms/tvos': { folder: {} }, + // './it-and-security/platforms/tvos/configuration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/android': { folder: {} }, + './it-and-security/platforms/android/configuration-profiles/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/android/managed-app-configurations/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/all/': { folder: {} }, + './it-and-security/platforms/all/icons/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/all/reports/.gitkeep': { copy: './gitkeep.template' }, + './it-and-security/platforms/all/policies/.gitkeep': { copy: './gitkeep.template' }, + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // β€’ e.g. create a folder: + // ``` + // './hey_look_a_folder': { folder: {} } + // ``` + // + // β€’ e.g. create a dynamically-named file relative to `scope.rootPath` + // (defined by the `filename` scope variable). + // + // The `template` helper reads the specified template, making the + // entire scope available to it (uses underscore/JST/ejs syntax). + // Then the file is copied into the specified destination (on the left). + // ``` + // './:filename': { template: 'example.template.js' }, + // ``` + // + // β€’ See https://sailsjs.com/docs/concepts/extending-sails/generators for more documentation. + // (Or visit https://sailsjs.com/support and talk to a maintainer of a core or community generator.) + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + }, + + + /** + * The absolute path to the `templates` for this generator + * (for use with the `template` and `copy` builtins) + * + * @type {String} + */ + templatesDirectory: require('path').resolve(__dirname, './templates') + +}; diff --git a/website/generators/gitops/templates/README.md.template b/website/generators/gitops/templates/README.md.template new file mode 100644 index 0000000000..30404ce4c5 --- /dev/null +++ b/website/generators/gitops/templates/README.md.template @@ -0,0 +1 @@ +TODO \ No newline at end of file diff --git a/website/generators/gitops/templates/default.yml.template b/website/generators/gitops/templates/default.yml.template new file mode 100644 index 0000000000..000f3cdb20 --- /dev/null +++ b/website/generators/gitops/templates/default.yml.template @@ -0,0 +1,138 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# default.yml +# +# Use this global manifest (`default.yml`) to configure +# top-level settings for your organization as a whole, and +# controls/reports/etc that apply to all of your fleets. +# +# To see all supported options, check out: +# β€’ https://fleetdm.com/docs/configuration/yaml-files +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +org_settings: + org_info: + ########################################################### + # The name of your organization is displayed to end users + # during the setup experience for new hardware, and to admins + # in the Fleet UI. + # + # Read more: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#org-info + ########################################################### + org_name: "My organization" + # ^TODO: Replace with the name of your organization + + server_settings: + ########################################################### + # The server URL where Fleet is running. + # + # β€’ No trailing slash at the end + # β€’ `http://` or `https://` at the beginning. + # + # (You can copy this from the URL bar in your browser.) + # + # Warning: Careful not to change this URL after enrolling + # Apple devices with MDM pointed at Fleet. If this URL changes + # and Apple hosts already have MDM turned on, then end users + # will have to take action to restore MDM functionality (due + # to the way Apple's device management protocol works.) + ########################################################### + server_url: "https://fleet.example.com" + # ^TODO: Replace with the URL where Fleet is running. + + ########################################################### + # Uncomment to use single sign-on (SSO) for admins accessing Fleet. + # + # Read more: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#sso-settings + # β€’ https://fleetdm.com/docs/deploy/single-sign-on-sso + ########################################################### + # sso_settings: + # idp_name: "Okta" # e.g. "Entra", "Okta", "Google Workspace", etc. (This appears to admins on the login screen as a "Sign in with ________" button.) + # metadata_url: "https://okta.com/replace-this-url" # This must exactly match the "IdP metadata URL" provided by your identity provider (IdP) when setting up this integration. + # entity_id: "fleet-admins" # This must exactly match the "Entity ID" field you chose when setting up this integration in your identity provider (IdP). + + mdm: + ########################################################### + # Uncomment to use single-sign on (SSO) to authenticate + # new computers enrolling in Fleet during end user setup. + # + # Read more: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#end-user-authentication + # β€’ https://fleetdm.com/guides/setup-experience#end-user-authentication + ########################################################### + # end_user_authentication: + # idp_name: "Okta" e.g. "Entra", "Okta", "Google Workspace", etc. (Displayed to end users.) + # metadata_url: "https://okta.com/replace-this-url" # This must exactly match the "IdP metadata URL" provided by your identity provider (IdP) when setting up this integration. + # entity_id: "fleet-end-users" # This must exactly match the "Entity ID" field you chose when setting up this integration in your identity provider (IdP). + + ########################################################### + # Uncomment when you are ready to start using zero-touch enrollment + # for Apple devices via Apple Business Manager (ABM). + # + # Read more: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#apple-business-manager + # β€’ https://fleetdm.com/guides/apple-mdm-setup#apple-business-manager-abm + ########################################################### + # apple_business_manager: + # - macos_fleet: "πŸ’» Workstations" # Where new macOS devices from ABM will appear + + ########################################################### + # Uncomment to start using Apple's volume purchase program (VPP) + # for making software available from the App Store and managing + # software licenses. + # + # Read more: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#volume-purchasing-program + # β€’ https://fleetdm.com/guides/apple-mdm-setup#volume-purchasing-program-vpp + ########################################################### + # volume_purchasing_program: + # - fleets: + # - "πŸ’» Workstations" + # - "πŸ“±πŸ” Personal mobile devices" + +controls: + ########################################################### + # Uncomment when you are ready to migrate Macs to Fleet + # from a different MDM server, especially devices running + # macOS ≀v26. + # + # For more information about what this does, see: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#macos-migration + # β€’ https://fleetdm.com/guides/mdm-migration#end-user-workflow + # + # Note: This is a global setting that cannot be applied per-fleet. + ########################################################### + # macos_migration: + # enable: true + # mode: voluntary # Start with "voluntary", then change this to "forced" closer to the deadline. + # webhook_url: "https://your-custom-webhook-or-one-provided-off-the-shelf-by-fleet-for-the-mdm-you-are-coming-from.example.com/webhooks/receive-from-fleet" + # # ^ When end users click "Migrate to Fleet", this webhook is triggered. + # # By convention it looks up the device and unmanages it in the old MDM, + # # then enrolls the device in Fleet. Unsure? Get help @ fleetdm.com/support. + + +########################################################### +# Labels are static or dynamic groupings of computers for +# scoping, reporting, and more. Use labels for everything +# from "x86 macs" to "finance department" to "needs new battery". +# +# For more, see: +# β€’ https://fleetdm.com/docs/configuration/yaml-files#labels +# β€’ https://fleetdm.com/guides/managing-labels-in-fleet +# +# (Optional) You can choose to manage labels in the Fleet GUI +# instead of in your git repo by **commenting out** `labels` +# below and removing the `labels/` folder. +# +# > Note: If you exclude `labels` from your git repo, then any +# > AI-assisted tools you may be using like Claude/Copilot/Kilocode +# > won't be able to see them as easily for use in scoping, +# > and could make it harder to do prompts like, for example: +# > "Make sure everyone in finance has the latest version of Excel" +########################################################### +labels: + - paths: ./labels/*.yml + diff --git a/website/generators/gitops/templates/fleets/personal-mobile-devices.yml.template b/website/generators/gitops/templates/fleets/personal-mobile-devices.yml.template new file mode 100644 index 0000000000..1eb85d9d78 --- /dev/null +++ b/website/generators/gitops/templates/fleets/personal-mobile-devices.yml.template @@ -0,0 +1,109 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# personal-mobile-devices.yml +# +# Use this fleet manifest to configure controls, software, +# and settings that apply only to computing devices (hosts) +# in this particular fleet. +# +# > Note: By convention, the "πŸ“±πŸ” Personal mobile devices" +# > fleet is where employee-owned iPhone and Android phones +# > are enrolled, for example as part of a BYOD ("bring your +# > own device") program. This allows for clear separation +# > and encourages employee freedom and privacy. +# +# To see all supported options, check out: +# β€’ https://fleetdm.com/docs/configuration/yaml-files +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +name: "πŸ“±πŸ” Personal mobile devices" +controls: + apple_setup: + ########################################################### + # Uncomment to use single-sign on (SSO) to authenticate + # end users enrolling their personal device. + # + # Read more: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#end-user-authentication + # β€’ https://fleetdm.com/guides/setup-experience#end-user-authentication + ########################################################### + # enable_end_user_authentication: true + + ########################################################### + # Presets, restrictions, and configs + # + # > Since the mobile devices in this fleet are personal + # > devices owned by employees, it can be appropriate to + # > cherry-pick only a very limited set of restrictions + # > and presets to maximize privacy and employee freedom. + # + # For more, see: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#apple-settings-and-windows-settings + # β€’ https://fleetdm.com/docs/configuration/yaml-files#android-settings + ########################################################### + apple_settings: + profiles: + # … e.g. + # - path: ../lib/ios/declaration-profiles/Passcode settings.json + # - path: ../lib/ios/configuration-profiles/self-service.mobileconfig + android_settings: + profiles: + certificates: + + ########################################################### + # Managed OS updates + # + # To enable and enforce managed OS updates on iOS/iPadOS, + # uncomment `ios_updates` and `ipados_updates`. + # + # See also: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#ios-updates + # β€’ https://fleetdm.com/docs/configuration/yaml-files#ipados-updates + # β€’ https://fleetdm.com/guides/enforce-os-updates#apple-macos-ios-and-ipados-end-user-experience + ########################################################### + # ios_updates: + # deadline: "2030-04-01" + # minimum_version: "18.5" + # ipados_updates: + # deadline: "2030-04-01" + # minimum_version: "18.5" + +########################################################### +# Apps to make available from the Apple App Store or Google Play +########################################################### +software: + app_store_apps: + ########################################################### + # iOS apps + ########################################################### + # … + # - app_store_id: "618783545" # Slack + # display_name: "Slack" + # self_service: true + # setup_experience: true + # platform: ios + # categories: + # - "Communication" + + ########################################################### + # iPadOS apps + ########################################################### + # … + # - app_store_id: "618783545" # Slack + # display_name: "Slack" + # self_service: true + # setup_experience: true + # platform: ipados + # categories: + # - "Productivity" + # - "Communication" + + ########################################################### + # Android apps + ########################################################### + # … + # - app_store_id: "com.Slack" # Slack + # platform: android + # display_name: "Slack" + # self_service: true + # setup_experience: true diff --git a/website/generators/gitops/templates/fleets/workstations.yml.template b/website/generators/gitops/templates/fleets/workstations.yml.template new file mode 100644 index 0000000000..8a5bca73d1 --- /dev/null +++ b/website/generators/gitops/templates/fleets/workstations.yml.template @@ -0,0 +1,191 @@ +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# workstations.yml +# +# Use this fleet manifest to configure controls, software, +# automations, policies, and reports that apply only to +# computing devices (hosts) in this particular fleet. +# +# > Note: By convention, the "πŸ’» Workstations" fleet is +# > where all company-owned laptops, PCs, and other +# > productivity endpoints (i.e. computers) are enrolled. +# +# To see all supported options, check out: +# β€’ https://fleetdm.com/docs/configuration/yaml-files +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +name: "πŸ’» Workstations" +controls: + apple_setup: + ########################################################### + # Configure the macOS setup experience + # + # (Optional) edit the automatic enrollment profile referenced + # here to change which items are skipped during macOS setup + # and other aspects of the end user's experience during + # their first few minutes with their new Mac. + # + # For more, see: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#macos-setup + # β€’ https://developer.apple.com/documentation/devicemanagement/profile + # β€’ https://support.apple.com/guide/deployment/automated-device-enrollment-management-dep73069dd57/web + ########################################################### + apple_setup_assistant: ../platforms/macos/enrollment-profiles/automatic-enrollment.dep.json + + ########################################################### + # Uncomment to use single-sign on (SSO) to authenticate + # end users during first-time setup of new computers. + # + # Read more: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#end-user-authentication + # β€’ https://fleetdm.com/guides/setup-experience#end-user-authentication + ########################################################### + # enable_end_user_authentication: true + + ########################################################### + # Configuration profiles + # + # For more, see: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#apple-settings-and-windows-settings + # + # Note: Instead of including all profiles with `paths`, + # you can also switch to using `path` and including each + # specific configuration profile one by one, which allows + # for scoping using labels. For example: + # ``` + # - path: ../platforms/macos/configuration-profiles/1password-managed-settings.mobileconfig + # labels_include_any: + # - "Macs with 1Password installed" + # ``` + ########################################################### + apple_settings: + profiles: + - paths: ../platforms/macos/declaration-profiles/*.json + - paths: ../platforms/macos/configuration-profiles/*.mobileconfig + windows_settings: + profiles: + - paths: ../platforms/windows/configuration-profiles/*.xml + + ########################################################### + # Managed disk encryption + # + # To enable and enforce disk encryption with key escrow on + # all supported platforms, uncomment `enable_disk_encryption`. + # + # Read more here: + # β€’ https://fleetdm.com/guides/enforce-disk-encryption + ########################################################### + # enable_disk_encryption: true + + ########################################################### + # Managed OS updates + # + # To enable and enforce managed OS updates on macOS/Windows, + # uncomment `macos_updates` and `windows_updates`. + # + # See also: + # β€’ https://fleetdm.com/docs/configuration/yaml-files#macos-updates + # β€’ https://fleetdm.com/docs/configuration/yaml-files#windows-updates + # β€’ https://fleetdm.com/guides/enforce-os-updates + ########################################################### + # macos_updates: + # deadline: "2030-04-01" + # minimum_version: "26.0" + # update_new_hosts: true + # windows_updates: + # deadline_days: 7 + # grace_period_days: 2 + + # TODO: mike: Go add documentation links for each section below + # (and write up the software section in here and the personal mobile devices fleet manifest) + + ########################################################### + # Script library + # + # Note: You probably don't need to change the next few lines. + # + # > To make a script available for use with Fleet for helpdesk + # > use cases and in your custom automations, just include it + # > in the appropriate folder for the primary platform where it + # > is intended to run. It will be included automatically + # > using `paths` below. + ########################################################### + scripts: + - paths: ../platforms/macos/scripts/*.sh + - paths: ../platforms/windows/scripts/*.ps1 + - paths: ../platforms/linux/scripts/*.sh + +########################################################### +# Reports +# +# Note: You probably don't need to change the next few lines. +# +# > To set up a report in Fleet for collecting data, include +# > it as a .yml file in `platforms/all/reports/` or if it +# > is specific to a particular platform, then in the appropriate +# > folder for that platform. It will be included automatically +# > using `paths` below. +########################################################### +reports: + - paths: ../platforms/all/reports/*.yml + - paths: ../platforms/macos/reports/*.yml + - paths: ../platforms/windows/reports/*.yml + - paths: ../platforms/linux/reports/*.yml + +########################################################### +# Policies & automations +# +# Note: You probably don't need to change the next few lines. +# +# > To set up a policy in Fleet to implement automations or +# > ensure compliance with organizational security standards +# > or regulations, include it as a .yml file in the +# > appropriate folder for the primary platform where it +# > is intended to run. It will be included automatically +# > using `paths` below. +########################################################### +policies: + - paths: ../platforms/macos/policies/*.yml + - paths: ../platforms/windows/policies/*.yml + - paths: ../platforms/linux/policies/*.yml + +########################################################### +# Software available for install +# +# Read more here: +# β€’ https://fleetdm.com/docs/configuration/yaml-files#software +########################################################### +software: + fleet_maintained_apps: + # macOS apps + # … + # - slug: slack/darwin # Slack for macOS + # self_service: true + # setup_experience: true + # categories: + # - Communication + # - Productivity + + # Windows apps + # … + # - slug: slack/windows # Slack for Windows + # self_service: true + # setup_experience: true + # categories: + # - Productivity + # - Communication + # labels_include_any: + # - "x86-based Windows hosts" + + packages: # Custom packages (if any) + # macOS custom packages + # … + + # Windows custom packages + # … + + # Linux custom packages + # … + + app_store_apps: # Apps to install via VPP from the macOS App Store, if any + # … diff --git a/website/generators/gitops/templates/github/fleet-gitops/action.yml.template b/website/generators/gitops/templates/github/fleet-gitops/action.yml.template new file mode 100644 index 0000000000..af453deca5 --- /dev/null +++ b/website/generators/gitops/templates/github/fleet-gitops/action.yml.template @@ -0,0 +1,59 @@ +name: fleetctl-gitops +description: Runs fleetctl gitops to apply configuration to Fleet + +inputs: + working-directory: + description: 'The working directory, which should be the root of the repository.' + default: './' + dry-run-only: + description: 'Whether to only run the fleetctl gitops commands in dry-run mode.' + default: 'false' + delete-other-fleets: + description: 'Whether to delete any other fleets which exist in the database but are not defined as .yml.' + default: 'true' + +runs: + using: "composite" + steps: + - name: Install fleetctl + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + FLEET_URL="${FLEET_URL%/}" + FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" --fail --silent | jq --raw-output '.version')" + DEFAULT_FLEETCTL_VERSION="4.80.2" + + # Decide which fleetctl version to install: + # If the server returns a clean version (e.g. 4.74.0), use that. + # If the server returns a snapshot (e.g. 0.0.0-SNAPSHOT-xxxxx) or is empty, pin to DEFAULT_FLEETCTL_VERSION. + if [[ -z "$FLEET_VERSION" ]]; then + INSTALL_VERSION="$DEFAULT_FLEETCTL_VERSION" + elif [[ "$FLEET_VERSION" == 0.0.0-SNAPSHOT* ]]; then + INSTALL_VERSION="$DEFAULT_FLEETCTL_VERSION" + elif [[ "$FLEET_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + INSTALL_VERSION="$FLEET_VERSION" + else + # Strip anything after + (e.g. 4.81.0+foobar -> 4.81.0) + FLEET_VERSION="${FLEET_VERSION%%\+*}" + if [[ "$FLEET_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + INSTALL_VERSION="$FLEET_VERSION" + else + INSTALL_VERSION="$DEFAULT_FLEETCTL_VERSION" + fi + fi + + echo "Installing fleetctl v$INSTALL_VERSION..." + npm install -g "fleetctl@$INSTALL_VERSION" || npm install -g fleetctl@latest + + - name: Configure fleetctl + shell: bash + working-directory: ${{ inputs.working-directory }} + run: fleetctl config set --address ${{ env.FLEET_URL }} --token ${{ env.FLEET_API_TOKEN }} + + - name: Run fleetctl gitops commands + shell: bash + working-directory: ${{ inputs.working-directory }} + env: + FLEET_DRY_RUN_ONLY: ${{ inputs.dry-run-only }} + FLEET_DELETE_OTHER_FLEETS: ${{ inputs.delete-other-fleets }} + run: ./.github/fleet-gitops/gitops.sh \ No newline at end of file diff --git a/website/generators/gitops/templates/github/fleet-gitops/gitops.sh.template b/website/generators/gitops/templates/github/fleet-gitops/gitops.sh.template new file mode 100644 index 0000000000..408d1677f9 --- /dev/null +++ b/website/generators/gitops/templates/github/fleet-gitops/gitops.sh.template @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# -e: Immediately exit if any command has a non-zero exit status. +# -x: Print all executed commands to the terminal. +# -u: Exit if an undefined variable is used. +# -o pipefail: Exit if any command in a pipeline fails. +set -exuo pipefail + +FLEET_GITOPS_DIR="${FLEET_GITOPS_DIR:-.}" +FLEET_GLOBAL_FILE="${FLEET_GLOBAL_FILE:-$FLEET_GITOPS_DIR/default.yml}" +FLEETCTL="${FLEETCTL:-fleetctl}" +FLEET_DRY_RUN_ONLY="${FLEET_DRY_RUN_ONLY:-false}" +FLEET_DELETE_OTHER_FLEETS="${FLEET_DELETE_OTHER_FLEETS:-true}" + +# Check for existence of the global config file (conventionally called default.yml) +# in case the script is used on repositories with only per-fleet .yml files. +if [ -f "$FLEET_GLOBAL_FILE" ]; then + # Validate that global file contains org_settings + grep -Exq "^org_settings:.*" "$FLEET_GLOBAL_FILE" +else + FLEET_DELETE_OTHER_FLEETS=false +fi + +# If you are using secrets to manage SSO metadata for Fleet SSO login or MDM SSO login, uncomment the below: + +# FLEET_SSO_METADATA=$( sed '2,$s/^/ /' <<< "${FLEET_MDM_SSO_METADATA}") +# FLEET_MDM_SSO_METADATA=$( sed '2,$s/^/ /' <<< "${FLEET_MDM_SSO_METADATA}") + +# Copy/pasting raw SSO metadata into GitHub secrets will result in malformed yaml. +# Adds spaces to all but the first line of metadata keeps the multiline string in bounds. + +if compgen -G "$FLEET_GITOPS_DIR"/fleets/*.yml > /dev/null; then + # Validate that every fleet has a unique name. + # This is a limited check that assumes all per-fleet .yml files contain the phrase: `name: ` + ! perl -nle 'print $1 if /^name:\s*(.+)$/' "$FLEET_GITOPS_DIR"/fleets/*.yml | sort | uniq -d | grep . -cq +fi + +args=() +if [ -f "$FLEET_GLOBAL_FILE" ]; then + args=(-f "$FLEET_GLOBAL_FILE") +fi + +for per_fleet_config_file in "$FLEET_GITOPS_DIR"/fleets/*.yml; do + if [ -f "$per_fleet_config_file" ]; then + args+=(-f "$per_fleet_config_file") + fi +done +if [ "$FLEET_DELETE_OTHER_FLEETS" = true ]; then + args+=(--delete-other-fleets) +fi + +# Dry run +$FLEETCTL gitops "${args[@]}" --dry-run +if [ "$FLEET_DRY_RUN_ONLY" = true ]; then + exit 0 +fi + +# Real run +$FLEETCTL gitops "${args[@]}" \ No newline at end of file diff --git a/website/generators/gitops/templates/github/workflows/fleet-gitops-workflow.yml.template b/website/generators/gitops/templates/github/workflows/fleet-gitops-workflow.yml.template new file mode 100644 index 0000000000..f7482be752 --- /dev/null +++ b/website/generators/gitops/templates/github/workflows/fleet-gitops-workflow.yml.template @@ -0,0 +1,46 @@ +name: 'Apply latest configuration to Fleet' + +on: + push: + branches: + - main + paths: + - '**' + pull_request: + paths: + - '**' + workflow_dispatch: # allows manual triggering + schedule: + - cron: '0 6 * * *' # Nightly 6AM UTC + +# Prevent concurrent runs of this workflow. +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +defaults: + run: + shell: bash + +# Limit permissions of GITHUB_TOKEN. +permissions: + contents: read + +jobs: + fleet-gitops: + runs-on: ubuntu-latest + steps: + - name: Checkout this repository + uses: actions/checkout@v4 + + - name: Apply latest configuration to Fleet + uses: ./.github/fleet-gitops + with: + # Run GitOps in dry-run mode for pull requests. + dry-run-only: ${{ github.event_name == 'pull_request' && 'true' || 'false' }} + env: + # These environment variables can be set as repository secrets, + # alongside any other environment variables mentioned in your .yml files. + FLEET_API_TOKEN: ${{ secrets.FLEET_API_TOKEN }} # required + + \ No newline at end of file diff --git a/website/generators/gitops/templates/gitignore.template b/website/generators/gitops/templates/gitignore.template new file mode 100644 index 0000000000..d9b06c8f80 --- /dev/null +++ b/website/generators/gitops/templates/gitignore.template @@ -0,0 +1,36 @@ +################################################ +# .gitignore +# +# This file (`.gitignore`) exists to tell git +# that certain files and/or directories should +# be ignored for the purposes of version control. +# +# This keeps tmp files from being accidentally +# uploaded to github.com/gitlab.com/etc. +# +################################################ + +# General +.DS_Store +.AppleDouble +.LSOverride +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk diff --git a/website/generators/gitops/templates/gitkeep.template b/website/generators/gitops/templates/gitkeep.template new file mode 100644 index 0000000000..e69de29bb2 diff --git a/website/generators/gitops/templates/gitlab-ci.yml.template b/website/generators/gitops/templates/gitlab-ci.yml.template new file mode 100644 index 0000000000..1120f12985 --- /dev/null +++ b/website/generators/gitops/templates/gitlab-ci.yml.template @@ -0,0 +1,27 @@ +fleet-gitops: + image: node:22 + variables: + FLEET_DRY_RUN_ONLY: true + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + FLEET_DRY_RUN_ONLY: false + - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + FLEET_DRY_RUN_ONLY: false + before_script: + - apt-get -qq update + - apt-get install -y 'jq=1.6-2.1*' + script: + - > + FLEET_VERSION="$(curl "$FLEET_URL/api/v1/fleet/version" --header "Authorization: Bearer $FLEET_API_TOKEN" --fail --silent | jq --raw-output '.version')" + - > + if [[ -n "$FLEET_VERSION" ]] ; then + npm install -g "fleetctl@$FLEET_VERSION" || npm install -g fleetctl + else + echo "Failed to get Fleet version from $FLEET_URL, installing latest version of fleetctl" + npm install -g fleetctl + fi + - fleetctl config set --address $FLEET_URL --token $FLEET_API_TOKEN + - ./.github/fleet-gitops/gitops.sh \ No newline at end of file diff --git a/website/generators/gitops/templates/labels/apple-silicon-macos-hosts.yml.template b/website/generators/gitops/templates/labels/apple-silicon-macos-hosts.yml.template new file mode 100644 index 0000000000..74d79166f5 --- /dev/null +++ b/website/generators/gitops/templates/labels/apple-silicon-macos-hosts.yml.template @@ -0,0 +1,5 @@ +- name: Apple Silicon macOS hosts + description: macOS hosts on Apple Silicon architecture + query: SELECT 1 FROM os_version WHERE arch LIKE 'ARM%'; + label_membership_type: dynamic + platform: darwin diff --git a/website/generators/gitops/templates/labels/arm-based-windows-hosts.yml.template b/website/generators/gitops/templates/labels/arm-based-windows-hosts.yml.template new file mode 100644 index 0000000000..808a5c24ac --- /dev/null +++ b/website/generators/gitops/templates/labels/arm-based-windows-hosts.yml.template @@ -0,0 +1,5 @@ +- name: ARM-based Windows hosts + description: Windows hosts on ARM architecture + query: SELECT 1 FROM os_version WHERE arch LIKE 'ARM%'; + label_membership_type: dynamic + platform: windows diff --git a/website/generators/gitops/templates/labels/debian-based-linux-hosts.yml.template b/website/generators/gitops/templates/labels/debian-based-linux-hosts.yml.template new file mode 100644 index 0000000000..c134c42080 --- /dev/null +++ b/website/generators/gitops/templates/labels/debian-based-linux-hosts.yml.template @@ -0,0 +1,4 @@ +- name: Debian-based Linux hosts + description: Linux hosts running on Debian-based operating systems + query: SELECT 1 FROM os_version WHERE platform_like = 'debian'; + label_membership_type: dynamic diff --git a/website/generators/gitops/templates/labels/x86-based-windows-hosts.yml.template b/website/generators/gitops/templates/labels/x86-based-windows-hosts.yml.template new file mode 100644 index 0000000000..33a59945f1 --- /dev/null +++ b/website/generators/gitops/templates/labels/x86-based-windows-hosts.yml.template @@ -0,0 +1,5 @@ +- name: x86-based Windows hosts + description: Windows hosts on x86 architecture + query: SELECT * FROM os_version WHERE arch NOT LIKE 'ARM%'; + label_membership_type: dynamic + platform: windows diff --git a/website/generators/gitops/templates/platforms/macos/enrollment-profiles/automatic-enrollment.dep.json.template b/website/generators/gitops/templates/platforms/macos/enrollment-profiles/automatic-enrollment.dep.json.template new file mode 100644 index 0000000000..13ec8dfb6a --- /dev/null +++ b/website/generators/gitops/templates/platforms/macos/enrollment-profiles/automatic-enrollment.dep.json.template @@ -0,0 +1,25 @@ +{ + "profile_name": "Automatic enrollment profile", + "allow_pairing": true, + "is_supervised": true, + "is_mdm_removable": false, + "org_magic": "1", + "language": "en", + "region": "US", + "skip_setup_items": [ + "AppleID", + "AppStore", + "Diagnostics", + "iCloudDiagnostics", + "iCloudStorage", + "Location", + "Payment", + "Privacy", + "Restore", + "ScreenTime", + "Siri", + "TermsOfAddress", + "TOS", + "UnlockWithWatch" + ] +} diff --git a/website/generators/gitops/templates/platforms/macos/policies/all-software-updates-installed.yml b/website/generators/gitops/templates/platforms/macos/policies/all-software-updates-installed.yml new file mode 100644 index 0000000000..85053221d4 --- /dev/null +++ b/website/generators/gitops/templates/platforms/macos/policies/all-software-updates-installed.yml @@ -0,0 +1,9 @@ +- name: macOS - All available software updates installed + query: SELECT 1 FROM software_update WHERE software_update_required = 0; + critical: false + description: This Mac may have outdated system software, which could lead to security vulnerabilities, performance issues, and incompatibility with other systems. + resolution: | + Please take some time and run all available updates from Software Update (ο£Ώ > System Settings > Software Update) and all available app store updates (ο£Ώ > App Store > Updates). + + If you see the message "This feature isn't available with the Apple Account you're currently using." you will need to delete and re-install the app. + platform: darwin \ No newline at end of file