{"id":23908310,"url":"https://github.com/hobadee/jamfvault","last_synced_at":"2026-02-04T07:01:59.040Z","repository":{"id":258148802,"uuid":"805049950","full_name":"Hobadee/JamfVault","owner":"Hobadee","description":"Syncs Jamf objects to disk so you can version them with GIT","archived":false,"fork":false,"pushed_at":"2024-10-16T07:22:45.000Z","size":67,"stargazers_count":3,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T08:38:56.997Z","etag":null,"topics":["jamf","jamf-pro","jamf-pro-api","jamfpro","sync"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hobadee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-23T19:33:07.000Z","updated_at":"2024-11-25T18:02:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"127f9b2b-02b1-4faf-9e64-3bf47867cd42","html_url":"https://github.com/Hobadee/JamfVault","commit_stats":null,"previous_names":["hobadee/jamfvault"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Hobadee/JamfVault","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hobadee%2FJamfVault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hobadee%2FJamfVault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hobadee%2FJamfVault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hobadee%2FJamfVault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hobadee","download_url":"https://codeload.github.com/Hobadee/JamfVault/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hobadee%2FJamfVault/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264419579,"owners_count":23605203,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jamf","jamf-pro","jamf-pro-api","jamfpro","sync"],"created_at":"2025-01-05T04:34:20.323Z","updated_at":"2026-02-04T07:01:53.981Z","avatar_url":"https://github.com/Hobadee.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JamfVault\nThis project helps sync Jamf items to a local repo, so they can be controlled with source-control, rather than in the Jamf UI without and SCM.\n\nThe end-goal of this project is to allow any push to a repository managing Jamf scripts (or other supported objects) to automatically update Jamf.\n\nCurrently this project is very basic.  It will only allow syncing of scripts, and must be run manually.  It should be fairly trivial to make a\nCI/CD worker which calls this, but that's a task for later.\n\n# TODO\n[x] Support syncing Scripts to/from Jamf\n\n[ ] 100% unit-testing coverage\n\n[ ] Support syncing Computer Extension Attributes (Particularly, the scripts of scripted EAs)\n\n[ ] Possibly support syncing Policies\n\n[ ] Possibly support syncing Profiles\n\n[ ] Possibly Support syncing Device/User Extension Attributes\n\n\n# Repository Organization\nThe organization of this project isn't great right now.  Re-organization is likely.\n\n# Testing\nWhile a few unit-tests currently exist, and did help some for development, test coverage is terrible.  It needs to be greatly improved.\n\n# Design\n1. Each Jamf itme has an underlying object to describe/store it\n2. An abstract strategy pattern is used to either `load()` or `save()` the object\n3. Concrete strategy patterns implement `load()`ing or `save()`ing to Jamf, Disk, or whatever other endpoints we decide to add.\n    We still deal entirely with objects here\n4. A Facade for each endpoint handles direct communication with the underlying system, such as Jamf or Disk.\n    These facades handle all conversion to/from objects and are the delineation between objects and APIs/Disk access\n\n# Syncing\nSince Jamf has a flat strucutre, but repos often have folders, the syncing should handle this gracefully.  As such, we will loop through directories\nto find what we need.  We match based on name.  Even though names in Jamf and Disk names can be changed, we use these as the Primary Key, so to speak,\nand do most of our matching off the name rather than the ID Jamf gives us.  (If an ID were to change on Disk accidentally and sync to Jamf, it could\nhave disasterous consequences.  Changing a name is much less likely to end in tragedy.)\n\nA note on syncing - while syncing *WILL* overwrite existing items, syncing will *NOT* currently delete items missing from one side or the other.  If we\ndecide to implement this in the future, it will probably be a new Strategy method.  (Such as `prune()` or something)\n\n## Folders\nWhen you sync, you will need to specify a root folder for the Disk Strategy.  Under this root folder, several additional folders will be used:\n\n### `scripts/` subdirectory\nThe `scripts/` subdirectory will be used for syncing Scripts.  Any file in here that ends with `.sh` or `.py` will be elegible for syncing.\n\nScripts synced from Jamf to Disk will be placed in additional subdirectories according to their Category.\n\n** IMPORTANT: ** Every Script must have a matching `.json` file that includes other Jamf settings.  Here is a minimal example:\n``` JSON\n{\n    \"categoryId\": -1,\n    \"categoryName\": \"NONE\",\n    \"info\": \"\",\n    \"notes\": \"\",\n    \"osRequirements\": \"\",\n    \"parameter10\": \"\",\n    \"parameter11\": \"\",\n    \"parameter4\": \"\",\n    \"parameter5\": \"\",\n    \"parameter6\": \"\",\n    \"parameter7\": \"\",\n    \"parameter8\": \"\",\n    \"parameter9\": \"\",\n    \"priority\": \"AFTER\"\n}\n\n```\nCurrently there is only very basic type-checking of the fields, so incorrect values for fields like \"priority\" are likely to cause issues.\n\nOptionally, a matching Markdown (`.md`) file may be included with notes, todos, or other information about the script.  Currently, nothing is done with\nthis file, but it is possible we do something with it in the future.  (We may decide to read this into the \"Notes\" field, for example.)\n\n### Other subdirectories\nAs additional Jamf modules are included, subdirectories for each module will be added.\n\n# Examples\nPlease see the `example.py` file\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhobadee%2Fjamfvault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhobadee%2Fjamfvault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhobadee%2Fjamfvault/lists"}