Documentation
¶
Overview ¶
Package scope provides shared schema attributes, builders, and validators for the <scope> block of Jamf Classic-API resources (policies, ebooks, mac applications, mobile device applications, OS X configuration profiles, mobile device configuration profiles, patch policies, restricted software).
Each scope block mirrors the Jamf Pro admin UI's three Scope tabs: the all-flags and every per-category target set live inside a `targets` sub-block, with `limitations` and `exclusions` as its siblings. Every attribute is Optional-only and follows per-category granular ownership: a declared category (including `[]`) is owned by Terraform, an omitted (null) category is left to the admin UI. Because the classic wire replaces the whole scope subtree once any category element is present in a PUT (wire-probed — see STYLE_GUIDE.md §Scope helper omission semantics), the "leave it alone" half is synthesised at apply time: the consuming resource's Update GETs the live scope, overlays the declared categories via the Merge* helpers in this package, and emits every merged category explicitly (empty wrappers included). Read-side, the RefreshManaged* helpers keep unmanaged categories out of state.
Sub-block items are modelled as flat Set<String> of IDs (or names for the directory-service categories), not nested objects. Server-augmented <name> and <udid> wire fields are discarded on read; only IDs round-trip through Terraform state. Full rule set in STYLE_GUIDE.md §Scope helper.
Cross-field invariants (all_computers ⇒ no per-computer or per-group targets, etc.) are enforced by AllFlagConflictsWith, a value-discriminated bool validator, and mirrored at apply time by the merge helpers: a true flag empties exactly its paired categories, and a declared paired category turns an unmanaged flag off (PickAllFlag). Per-resource exceptions (e.g. RestrictedSoftware rejects limitations entirely, and honours the admin UI by pairing buildings and departments with all_computers too) live in the resource package, not here.
Index ¶
- func AllFlagConflictsWith(conflicts ...path.Expression) validator.Bool
- func AllFlagsConflictWith(others []path.Expression, conflicts ...path.Expression) validator.Bool
- func BuildIDSlice[T any](ctx context.Context, set types.Set, mk func(int) T) (*[]T, diag.Diagnostics)
- func BuildImpactScope(ctx context.Context, in ImpactInputs) impact.Scope
- func BuildNameSlice[T any](ctx context.Context, set types.Set, mk func(string) T) (*[]T, diag.Diagnostics)
- func BuildSiteObject(siteID types.String) *proclassic.SiteObject
- func ComputerImpactScope(ctx context.Context, m *ComputerScopeModel) impact.Scope
- func ComputerImpactScopeNoIbeacons(ctx context.Context, m *ComputerScopeModelNoIbeacons) impact.Scope
- func ComputerScopeAttributes(opts ComputerScopeOptions) map[string]schema.Attribute
- func EmptyStringSet() types.Set
- func FlattenIDNameSet(ctx context.Context, items *[]proclassic.IDName) types.Set
- func FlattenIDSlice[T any](ctx context.Context, items *[]T, extract func(T) *int) (types.Set, diag.Diagnostics)
- func FlattenNameSet(ctx context.Context, items *[]proclassic.IDName) types.Set
- func FlattenNameSlice[T any](ctx context.Context, items *[]T, extract func(T) *string) (types.Set, diag.Diagnostics)
- func FlattenSiteObject(site *proclassic.SiteObject) (*string, *string)
- func HasMembers(sets ...types.Set) bool
- func IDSetAttribute(attrLabel string) schema.SetAttribute
- func MobileImpactScope(ctx context.Context, m *MobileScopeModel) impact.Scope
- func MobileImpactScopeNoIbeacons(ctx context.Context, m *MobileScopeModelNoIbeacons) impact.Scope
- func MobileScopeAttributes(opts MobileScopeOptions) map[string]schema.Attribute
- func NameSetAttribute(attrLabel string) schema.SetAttribute
- func NumericIDs() validator.Set
- func OmitAllFlagNote(paired string) string
- func PickAllFlag(declared, server types.Bool, paired ...types.Set) types.Bool
- func RefreshManagedBool(current types.Bool, wire *bool, includeUnmanaged bool) types.Bool
- func RefreshManagedSet(current, wire types.Set, includeUnmanaged bool) types.Set
- func UserScopeAttributes() map[string]schema.Attribute
- func ValidateDirectoryServiceUserGroupNames(ctx context.Context, searcher ldapgroups.Searcher, set types.Set, ...) diag.Diagnostics
- type ComputerScopeExclusionsModel
- type ComputerScopeExclusionsModelNoIbeacons
- type ComputerScopeLimitationsModel
- type ComputerScopeLimitationsModelNoIbeacons
- type ComputerScopeModel
- type ComputerScopeModelNoIbeacons
- type ComputerScopeOptions
- type ComputerScopeTargetsModel
- type ImpactInputs
- type MobileScopeExclusionsModel
- type MobileScopeExclusionsModelNoIbeacons
- type MobileScopeLimitationsModel
- type MobileScopeLimitationsModelNoIbeacons
- type MobileScopeModel
- type MobileScopeModelNoIbeacons
- type MobileScopeOptions
- type MobileScopeTargetsModel
- type SecondaryEstate
- type UserScopeExclusionsModel
- type UserScopeLimitationsModel
- type UserScopeModel
- type UserScopeTargetsModel
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AllFlagConflictsWith ¶
func AllFlagConflictsWith(conflicts ...path.Expression) validator.Bool
AllFlagConflictsWith is a value-discriminated bool validator: when the attribute is true, every path in conflicts must be null, unknown, or empty. It is the scope-specific replacement for boolvalidator.ConflictsWith, which triggers on any value (true or false) and so cannot express the "only when true" semantics that all_computers, all_mobile_devices, and all_jss_users require.
Errors attach to each conflicting attribute path per STYLE_GUIDE §Cross-field validation. The validator emits one diagnostic per violating path so the user sees every conflict in a single pass.
func AllFlagsConflictWith ¶ added in v1.4.0
func AllFlagsConflictWith(others []path.Expression, conflicts ...path.Expression) validator.Bool
AllFlagsConflictWith is the validator for the combination rule that AllFlagConflictsWith cannot express: it fires only when this flag AND every sibling flag in others are true, and then requires every path in conflicts to be null, unknown, or empty. It exists for the admin UI's ebook scope, which offers no buildings, departments or classes once all computers, all mobile devices and all users are selected together. Attach it to ONE of the flags — attaching it to each would repeat the same diagnostics.
func BuildIDSlice ¶
func BuildIDSlice[T any]( ctx context.Context, set types.Set, mk func(int) T, ) (*[]T, diag.Diagnostics)
BuildIDSlice projects a Terraform Set<String> of numeric Jamf Pro IDs into the SDK pointer-slice expected by classic scope sub-blocks. mk is the per-call constructor that wraps each parsed int ID in the resource's SDK item type.
Ownership-preserving omission semantics (wire-probed — see STYLE_GUIDE.md §Scope helper omission semantics):
- null / unknown → nil: the category is unmanaged, the SDK omits the parent XML element entirely.
- empty (declared `[]`, or an empty merged value on the read-merge-write update path) → a non-nil pointer to an EMPTY slice: the caller assigns the parent wrapper, which marshals as an empty element (e.g. `<computer_groups></computer_groups>`). The empty element is what clears the category — a scope PUT replaces the whole subtree once any category element is present, and a body whose scope has no category elements at all is ignored by the server, so "clear the last member" only works via the explicit empty wrapper.
Element parse errors do not short-circuit — every failure is collected in one pass so the user sees them all at once. Returns (nil, diags) when any element fails to parse as an integer.
func BuildImpactScope ¶
func BuildImpactScope(ctx context.Context, in ImpactInputs) impact.Scope
BuildImpactScope converts a scope block into the shape the impact package counts.
func BuildNameSlice ¶
func BuildNameSlice[T any]( ctx context.Context, set types.Set, mk func(string) T, ) (*[]T, diag.Diagnostics)
BuildNameSlice projects a Terraform Set<String> of names into the SDK pointer-slice expected by name-only scope sub-blocks (directory_service_or_local_user_names, directory_service_user_group_names, limit_to_user_group_names). Same omission semantics as BuildIDSlice — null/unknown → nil (unmanaged, element omitted); empty → non-nil empty slice (declared clear, empty element emitted).
func BuildSiteObject ¶
func BuildSiteObject(siteID types.String) *proclassic.SiteObject
BuildSiteObject parses a Terraform string site ID into a ProClassic SiteObject for write payloads. Returns nil for null/unknown/empty/un-parseable input so the SDK omits the site element entirely.
func ComputerImpactScope ¶
func ComputerImpactScope(ctx context.Context, m *ComputerScopeModel) impact.Scope
ComputerImpactScope converts a computer scope block. A nil model yields an empty scope, which reports nothing.
func ComputerImpactScopeNoIbeacons ¶
func ComputerImpactScopeNoIbeacons(ctx context.Context, m *ComputerScopeModelNoIbeacons) impact.Scope
ComputerImpactScopeNoIbeacons converts the no-iBeacon computer scope variant.
func ComputerScopeAttributes ¶
func ComputerScopeAttributes(opts ComputerScopeOptions) map[string]schema.Attribute
ComputerScopeAttributes returns the attribute map for a computer-scoped classic resource's <scope> block (targets + limitations + exclusions), mirroring the Jamf Pro admin UI's Targets / Limitations / Exclusions tabs. The all-flags and every target category live inside the `targets` sub-block; each target category is a flat Set<String> of numeric Jamf Pro IDs and directory-service categories carry names. The caller wraps the map in its own schema.SingleNestedAttribute with a resource-specific description:
"scope": schema.SingleNestedAttribute{
MarkdownDescription: "...",
Optional: true,
Attributes: scope.ComputerScopeAttributes(scope.ComputerScopeOptions{IncludeIbeacons: true}),
}
Every attribute in the block — the per-category sets and the all-flags — follows per-category granular ownership: omitted means "not managed by Terraform" (preserved on the wire via read-merge-write in the consuming resource's update), declared means owned. The all-flags carry the value-discriminated AllFlagConflictsWith validators (relative paths, so they resolve against their siblings inside `targets`). See STYLE_GUIDE.md §Scope helper.
func EmptyStringSet ¶
EmptyStringSet returns a known, empty Set<String>. It is the canonical "no members" value for a MANAGED classic scope target category: a declared `[]` config plans as `[]`, the read path flattens an empty wire result for a managed category to `[]`, and the read-merge-write update path uses it to normalise absent server sub-blocks. Unmanaged (omitted) categories are null, never `[]` — the null/empty distinction carries the ownership semantics. See scope/schema.go.
func FlattenIDNameSet ¶
FlattenIDNameSet projects a ProClassic []IDName pointer-slice into a Terraform Set<String> of the items' integer IDs. Thin, diagnostics-dropping wrapper over FlattenIDSlice for the common proclassic.IDName shape that classic scope and reference sub-blocks use throughout. Returns an empty set for nil/empty input (empty is the canonical "no members" value — see FlattenIDSlice).
func FlattenIDSlice ¶
func FlattenIDSlice[T any]( ctx context.Context, items *[]T, extract func(T) *int, ) (types.Set, diag.Diagnostics)
FlattenIDSlice projects an SDK pointer-slice into a Terraform Set<String> of ID values. extract returns the int ID from the SDK item type. Returns an empty Set<String> (EmptyStringSet) if items is nil or empty: empty is the canonical "no members" value for a managed category, so an absent wire sub-block reads back as `[]`, not null. Ownership gating (unmanaged stays null) happens at the call site via RefreshManagedSet, not here. Items whose extract returns nil are skipped — server should not return such items but defend.
func FlattenNameSet ¶
FlattenNameSet projects a ProClassic []IDName pointer-slice into a Terraform Set<String> of the items' names. Name-only sibling of FlattenIDNameSet.
func FlattenNameSlice ¶
func FlattenNameSlice[T any]( ctx context.Context, items *[]T, extract func(T) *string, ) (types.Set, diag.Diagnostics)
FlattenNameSlice projects an SDK pointer-slice into a Terraform Set<String> of name values. extract returns the name pointer from the SDK item type. Returns an empty Set<String> (EmptyStringSet) on nil/empty input — see FlattenIDSlice for the empty-is-canonical rationale. Items whose extract returns nil or empty string are skipped — server-side blanks have no meaningful TF representation.
func FlattenSiteObject ¶
func FlattenSiteObject(site *proclassic.SiteObject) (*string, *string)
FlattenSiteObject unpacks a ProClassic SiteObject (nil-able integer ID + name) into (idString, name) pointers for state assignment. Returns (nil, nil) when the site is absent; the ID is rendered as its decimal string when present. The name is nilled for the "NONE"/unassigned sentinel (id nil or <= 0): the classic GET nondeterministically echoes or omits "<name>NONE</name>" there, so trusting it would flip the derived site_name between reads (ImportStateVerify / "inconsistent result after apply"). See STYLE_GUIDE §Server-derived computed fields.
func HasMembers ¶ added in v1.4.0
HasMembers reports whether any of the given declared sets carries at least one element. A null or unknown set carries none.
func IDSetAttribute ¶
func IDSetAttribute(attrLabel string) schema.SetAttribute
IDSetAttribute returns the canonical Set<String> schema for ID-bearing classic-API scope target categories. Used for: computers, computer_groups, mobile_devices, mobile_device_groups, buildings, departments, jss_users, jss_user_groups, classes, network_segments, ibeacons.
attrLabel is interpolated into the MarkdownDescription as the human-readable singular form (e.g. "computer", "computer group", "building").
These sets are Optional-only — per-category granular ownership (wire-probed, see STYLE_GUIDE.md §Scope helper omission semantics):
- OMITTED (null): the category is not managed by Terraform. It never enters state, and on update the input builder re-emits the live server members for it (read-merge-write), so values maintained in the admin UI are preserved.
- DECLARED (including `[]`): Terraform owns the category. `[]` clears it; members drift-revert on refresh.
The null/empty distinction is load-bearing, which is why these attributes must not be Computed: a Computed attribute cannot keep a null config null once the server echoes a value.
func MobileImpactScope ¶
func MobileImpactScope(ctx context.Context, m *MobileScopeModel) impact.Scope
MobileImpactScope converts a mobile device scope block.
func MobileImpactScopeNoIbeacons ¶
func MobileImpactScopeNoIbeacons(ctx context.Context, m *MobileScopeModelNoIbeacons) impact.Scope
MobileImpactScopeNoIbeacons converts the no-iBeacon mobile scope variant.
func MobileScopeAttributes ¶
func MobileScopeAttributes(opts MobileScopeOptions) map[string]schema.Attribute
MobileScopeAttributes returns the attribute map for a mobile-device-scoped classic resource's <scope> block (targets + limitations + exclusions), mirroring the Jamf Pro admin UI's Targets / Limitations / Exclusions tabs. The all-flags and every target category live inside the `targets` sub-block; each target category is a flat Set<String> of numeric Jamf Pro IDs and directory-service categories carry names. The caller wraps the map in its own schema.SingleNestedAttribute with a resource-specific description:
"scope": schema.SingleNestedAttribute{
MarkdownDescription: "...",
Optional: true,
Attributes: scope.MobileScopeAttributes(scope.MobileScopeOptions{IncludeIbeacons: true}),
}
Every attribute in the block — the per-category sets and the all-flags — follows per-category granular ownership: omitted means "not managed by Terraform" (preserved on the wire via read-merge-write in the consuming resource's update), declared means owned. The all-flags carry the value-discriminated AllFlagConflictsWith validators (relative paths, so they resolve against their siblings inside `targets`). See STYLE_GUIDE.md §Scope helper.
func NameSetAttribute ¶
func NameSetAttribute(attrLabel string) schema.SetAttribute
NameSetAttribute returns the canonical Set<String> schema for name-only classic-API scope target categories. Used for: directory_service_or_local_user_names, directory_service_user_group_names, limit_to_user_group_names. Same granular-ownership semantics as IDSetAttribute: omit = not managed (preserved on the wire), `[]` = clear.
func NumericIDs ¶
NumericIDs is the element validator for the ID-bearing scope target categories (IDSetAttribute). Every Jamf Pro object referenced by ID — computers, groups, buildings, departments, users, network segments, iBeacons — carries a numeric integer identifier. This catches the common footgun of passing a UUID (or any other non-numeric handle) where a numeric ID is required: without it the mistake surfaces only during apply as an opaque `strconv.Atoi: parsing "…": invalid syntax` from the input builder, with no attribute path. Here it is reported at plan time, pinned to the offending element, with actionable guidance.
The parse mirrors the input builder (BuildIDSlice → strconv.Atoi) exactly, so the validator rejects precisely the values that would fail the write and nothing more — no false rejects. Null/unknown elements are deferred per STYLE_GUIDE §Config-time validators, so IDs sourced from other resources or variables are not flagged before they resolve.
func OmitAllFlagNote ¶ added in v1.4.0
OmitAllFlagNote is the closing sentence of every all-flag attribute description. paired names the categories the flag conflicts with: declaring any of them while the flag is omitted turns the toggle off at apply (see PickAllFlag), so the omit-means-preserve contract carries that one exception.
func PickAllFlag ¶ added in v1.4.0
PickAllFlag resolves an all-flag for the read-merge-write overlay. A declared flag always wins; otherwise a declared non-empty paired category turns the flag off — the configuration owns the audience through those members, and a preserved true from the admin UI would wipe them. With neither, the live value is kept (false when there is none). paired are the PLAN's sets for the categories the flag conflicts with, never the merged ones.
func RefreshManagedBool ¶
RefreshManagedBool is the all-flag sibling of RefreshManagedSet. A nil wire pointer (the classic GET always echoes the flags, so this is defensive) keeps the current value rather than nulling a managed flag.
func RefreshManagedSet ¶
RefreshManagedSet gates a scope category refresh on ownership: the wire value is adopted only when the category is managed — non-null in `current`, the model being written to state (the plan on create/update, the prior state on read; see STYLE_GUIDE.md §Scope helper for why the gate target is never a separate prior-state reference). An unmanaged (null) category stays null so members maintained in the admin UI never enter state or plans.
includeUnmanaged bypasses the gate for the two hydrate-everything paths — import and `terraform query` config generation — where there is no plan to stay consistent with and full visibility is the point.
func UserScopeAttributes ¶
UserScopeAttributes returns the attribute map for a user-based classic resource's <scope> block (targets + limitations + exclusions). This is the THIRD scope shape (distinct from ComputerScopeAttributes / MobileScopeAttributes): targets are Jamf Pro users and Jamf Pro user groups (id-keyed) plus the all_jss_users flag; limitations and exclusions carry directory-service (LDAP) user groups by NAME. The caller wraps the map in its own schema.SingleNestedAttribute with a resource-specific description:
"scope": schema.SingleNestedAttribute{
MarkdownDescription: "...",
Optional: true,
Attributes: scope.UserScopeAttributes(),
}
Every attribute in the block follows per-category granular ownership: omitted means "not managed by Terraform" (preserved on the wire via read-merge-write in the consuming resource's update), declared means owned. all_jss_users (inside the `targets` sub-block) is Optional-only and carries the value-discriminated AllFlagConflictsWith validator (relative paths, so they resolve against its siblings inside `targets`).
Consumed by vpp_invitation and vpp_assignment. The build/flatten glue stays per-resource because VppInvitation* and VppAssignment* are distinct generated SDK structs with no shared interface (see STYLE_GUIDE.md §Scope helper).
func ValidateDirectoryServiceUserGroupNames ¶
func ValidateDirectoryServiceUserGroupNames(ctx context.Context, searcher ldapgroups.Searcher, set types.Set, attrPath path.Path) diag.Diagnostics
ValidateDirectoryServiceUserGroupNames is a plan-time preflight for a scope `directory_service_user_group_names` set. The classic scope endpoints match these names against the tenant's configured directory service and reject unknown names at apply time with an opaque 409 ("Problem matching limitation user group"). This surfaces a hint at plan time with a clear, per-name message — call it from a scope-bearing resource's ModifyPlan, once per set (limitations and exclusions each have their own).
It is ADVISORY (never blocks the plan): a no-match is a WARNING, not an error. Blocking would break the legitimate bootstrap case — creating the directory and a group-scoped resource in the same apply, where the directory does not exist yet at plan time. A genuinely wrong name still fails loudly at apply (the write retries the 409 for a bounded window, then surfaces it). See helpers.IsDirectoryGroupMatchConflict / the resources' retry-on-write.
Behaviour:
- nil searcher, or null/unknown set: no-op (nothing to check, or the provider is not yet configured).
- unknown / null individual elements (e.g. a name interpolated from another resource's not-yet-known attribute): skipped — they cannot be validated at plan time.
- a name resolving to >=1 exact directory group (on any server): OK.
- a name with no exact match: a WARNING (bootstrap-friendly; enforced at apply).
- a search transport error: a WARNING (the directory API is unreachable / not yet configured; the server still enforces on apply).
Types ¶
type ComputerScopeExclusionsModel ¶
type ComputerScopeExclusionsModel struct {
ComputerIDs types.Set `tfsdk:"computer_ids"`
ComputerGroupIDs types.Set `tfsdk:"computer_group_ids"`
BuildingIDs types.Set `tfsdk:"building_ids"`
DepartmentIDs types.Set `tfsdk:"department_ids"`
UserIDs types.Set `tfsdk:"user_ids"`
UserGroupIDs types.Set `tfsdk:"user_group_ids"`
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
IbeaconIDs types.Set `tfsdk:"ibeacon_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
ComputerScopeExclusionsModel models <scope><exclusions> for an iBeacon-bearing computer-scoped resource.
type ComputerScopeExclusionsModelNoIbeacons ¶
type ComputerScopeExclusionsModelNoIbeacons struct {
ComputerIDs types.Set `tfsdk:"computer_ids"`
ComputerGroupIDs types.Set `tfsdk:"computer_group_ids"`
BuildingIDs types.Set `tfsdk:"building_ids"`
DepartmentIDs types.Set `tfsdk:"department_ids"`
UserIDs types.Set `tfsdk:"user_ids"`
UserGroupIDs types.Set `tfsdk:"user_group_ids"`
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
ComputerScopeExclusionsModelNoIbeacons models <scope><exclusions> for a computer-scoped resource whose endpoint omits iBeacon scope.
type ComputerScopeLimitationsModel ¶
type ComputerScopeLimitationsModel struct {
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
IbeaconIDs types.Set `tfsdk:"ibeacon_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
ComputerScopeLimitationsModel models <scope><limitations> for an iBeacon-bearing computer-scoped resource.
type ComputerScopeLimitationsModelNoIbeacons ¶
type ComputerScopeLimitationsModelNoIbeacons struct {
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
ComputerScopeLimitationsModelNoIbeacons models <scope><limitations> for a computer-scoped resource whose endpoint omits iBeacon scope.
type ComputerScopeModel ¶
type ComputerScopeModel struct {
Targets *ComputerScopeTargetsModel `tfsdk:"targets"`
Limitations *ComputerScopeLimitationsModel `tfsdk:"limitations"`
Exclusions *ComputerScopeExclusionsModel `tfsdk:"exclusions"`
}
ComputerScopeModel is the Terraform model for a Jamf classic computer-scope <scope> block. Field names + tfsdk tags match ComputerScopeAttributes (with IncludeIbeacons=true). Every target category is a flat Set<String> of numeric Jamf Pro IDs; directory-service categories carry names. The wire elements for the user categories are <jss_users>/<jss_user_groups>; the UI-canonical attribute names user_ids/user_group_ids are used here.
Consumed by policy and os_x_configuration_profile (both iBeacon-bearing). Resources whose endpoint omits iBeacon scope (mac_application) cannot reuse this struct — the framework matches model fields to schema attributes exactly, so a no-iBeacon schema needs its own model. See STYLE_GUIDE.md §Scope helper.
func MergeComputerScope ¶
func MergeComputerScope(plan, server *ComputerScopeModel) *ComputerScopeModel
MergeComputerScope overlays a declared iBeacon-bearing computer scope onto the server's current scope. plan nil (scope unmanaged) returns nil — the caller must not send a scope element at all. server nil is treated as an empty live scope.
func (ComputerScopeModel) TargetsOrZero ¶
func (m ComputerScopeModel) TargetsOrZero() ComputerScopeTargetsModel
TargetsOrZero returns the targets sub-model, or a zero value with null sets when the block was omitted, so input-builders can read target fields without a nil-guard. The omission semantics in BuildIDSlice treat null sets as absent.
type ComputerScopeModelNoIbeacons ¶
type ComputerScopeModelNoIbeacons struct {
Targets *ComputerScopeTargetsModel `tfsdk:"targets"`
Limitations *ComputerScopeLimitationsModelNoIbeacons `tfsdk:"limitations"`
Exclusions *ComputerScopeExclusionsModelNoIbeacons `tfsdk:"exclusions"`
}
ComputerScopeModelNoIbeacons is the Terraform model for a computer-scope <scope> block built with ComputerScopeAttributes(IncludeIbeacons=false). The target fields are identical to ComputerScopeModel; only the limitations and exclusions sub-blocks differ (no ibeacon_ids). The framework matches model fields to schema attributes exactly, so a no-iBeacon schema needs its own model rather than reusing ComputerScopeModel (which carries IbeaconIDs).
Consumed by mac_app_store_app, whose /macapplications endpoint silently drops iBeacon limitations/exclusions (wire-probed). See STYLE_GUIDE.md §Scope helper.
func MergeComputerScopeNoIbeacons ¶
func MergeComputerScopeNoIbeacons(plan, server *ComputerScopeModelNoIbeacons) *ComputerScopeModelNoIbeacons
MergeComputerScopeNoIbeacons is MergeComputerScope for the no-iBeacon model variant (mac_app_store_app).
func (ComputerScopeModelNoIbeacons) TargetsOrZero ¶
func (m ComputerScopeModelNoIbeacons) TargetsOrZero() ComputerScopeTargetsModel
TargetsOrZero returns the targets sub-model, or a zero value with null sets when the block was omitted. See ComputerScopeModel.TargetsOrZero.
type ComputerScopeOptions ¶
type ComputerScopeOptions struct {
// IncludeIbeacons adds ibeacon_ids to the limitations and exclusions
// sub-blocks. Resources whose endpoint ignores iBeacon scope must leave
// this false so the attribute is absent rather than silently dropped.
IncludeIbeacons bool
}
ComputerScopeOptions gates the handful of per-resource deltas in the otherwise-shared Jamf classic computer-scope block. Today the only axis is iBeacon support: policy and os_x_configuration_profile carry iBeacon limitations/exclusions; the macapplications endpoint silently drops them (wire-probed), so mac_application sets IncludeIbeacons=false to avoid a permadiff. See STYLE_GUIDE.md §Scope helper.
type ComputerScopeTargetsModel ¶
type ComputerScopeTargetsModel struct {
AllComputers types.Bool `tfsdk:"all_computers"`
AllJssUsers types.Bool `tfsdk:"all_jss_users"`
ComputerIDs types.Set `tfsdk:"computer_ids"`
ComputerGroupIDs types.Set `tfsdk:"computer_group_ids"`
BuildingIDs types.Set `tfsdk:"building_ids"`
DepartmentIDs types.Set `tfsdk:"department_ids"`
UserIDs types.Set `tfsdk:"user_ids"`
UserGroupIDs types.Set `tfsdk:"user_group_ids"`
}
ComputerScopeTargetsModel models <scope> targets — the all-flags plus the per-category ID sets, mirroring the admin UI's Targets tab. Shared by both iBeacon variants (targets do not carry iBeacons).
type ImpactInputs ¶
type ImpactInputs struct {
// DeviceType is the estate the scope's percentages are measured against.
// DeviceTypeAny is for a resource that targets both, such as an ebook.
DeviceType impact.DeviceType
// DeviceAttr and GroupAttr are the configuration names of the device and
// group categories, e.g. "computer_ids" and "computer_group_ids". They appear
// in the attribute paths an alert cites.
DeviceAttr string
GroupAttr string
// GroupEstate is the estate the group ids belong to. Defaults to DeviceType.
GroupEstate impact.DeviceType
// Targets.
All types.Bool
DeviceIDs types.Set
GroupIDs types.Set
AllJssUsers types.Bool
BuildingIDs types.Set
DepartmentIDs types.Set
UserIDs types.Set
UserGroupIDs types.Set
ClassIDs types.Set
SecondaryDevices *SecondaryEstate
// Limitations.
LimitNetworkSegmentIDs types.Set
LimitIbeaconIDs types.Set
LimitUserNames types.Set
LimitDSGroupNames types.Set
// Exclusions.
ExcludeDeviceIDs types.Set
ExcludeGroupIDs types.Set
ExcludeBuildingIDs types.Set
ExcludeDepartmentIDs types.Set
ExcludeUserIDs types.Set
ExcludeUserGroupIDs types.Set
ExcludeNetworkSegmentIDs types.Set
ExcludeIbeaconIDs types.Set
ExcludeUserNames types.Set
ExcludeDSGroupNames types.Set
ExcludeSecondaryDevices *SecondaryEstate
}
ImpactInputs is a scope block flattened to its individual attributes, so any model shape can feed the one classification.
Every field is optional: an unset collection is null, which the builder treats as absent. A resource therefore populates only the categories its own scope supports — a patch policy has no user targets, a restricted software record has no limitations block — and the omitted ones report nothing.
type MobileScopeExclusionsModel ¶
type MobileScopeExclusionsModel struct {
MobileDeviceIDs types.Set `tfsdk:"mobile_device_ids"`
MobileDeviceGroupIDs types.Set `tfsdk:"mobile_device_group_ids"`
BuildingIDs types.Set `tfsdk:"building_ids"`
DepartmentIDs types.Set `tfsdk:"department_ids"`
UserIDs types.Set `tfsdk:"user_ids"`
UserGroupIDs types.Set `tfsdk:"user_group_ids"`
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
IbeaconIDs types.Set `tfsdk:"ibeacon_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
MobileScopeExclusionsModel models <scope><exclusions> for an iBeacon-bearing mobile-device-scoped resource.
type MobileScopeExclusionsModelNoIbeacons ¶
type MobileScopeExclusionsModelNoIbeacons struct {
MobileDeviceIDs types.Set `tfsdk:"mobile_device_ids"`
MobileDeviceGroupIDs types.Set `tfsdk:"mobile_device_group_ids"`
BuildingIDs types.Set `tfsdk:"building_ids"`
DepartmentIDs types.Set `tfsdk:"department_ids"`
UserIDs types.Set `tfsdk:"user_ids"`
UserGroupIDs types.Set `tfsdk:"user_group_ids"`
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
MobileScopeExclusionsModelNoIbeacons models <scope><exclusions> for a mobile-device-scoped resource whose endpoint omits iBeacon scope.
type MobileScopeLimitationsModel ¶
type MobileScopeLimitationsModel struct {
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
IbeaconIDs types.Set `tfsdk:"ibeacon_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
MobileScopeLimitationsModel models <scope><limitations> for an iBeacon-bearing mobile-device-scoped resource.
type MobileScopeLimitationsModelNoIbeacons ¶
type MobileScopeLimitationsModelNoIbeacons struct {
NetworkSegmentIDs types.Set `tfsdk:"network_segment_ids"`
DirectoryServiceOrLocalUserNames types.Set `tfsdk:"directory_service_or_local_user_names"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
MobileScopeLimitationsModelNoIbeacons models <scope><limitations> for a mobile-device-scoped resource whose endpoint omits iBeacon scope.
type MobileScopeModel ¶
type MobileScopeModel struct {
Targets *MobileScopeTargetsModel `tfsdk:"targets"`
Limitations *MobileScopeLimitationsModel `tfsdk:"limitations"`
Exclusions *MobileScopeExclusionsModel `tfsdk:"exclusions"`
}
MobileScopeModel is the Terraform model for a Jamf classic mobile-device-scope <scope> block. Field names + tfsdk tags match MobileScopeAttributes (with IncludeIbeacons=true). Every target category is a flat Set<String> of numeric Jamf Pro IDs; directory-service categories carry names. The wire elements for the user categories are <jss_users>/<jss_user_groups>; the UI-canonical attribute names user_ids/user_group_ids are used here.
Consumed by mobile_device_configuration_profile (iBeacon-bearing). Resources whose endpoint omits iBeacon scope (mobile_device_app) cannot reuse this struct — the framework matches model fields to schema attributes exactly, so a no-iBeacon schema needs its own model. See STYLE_GUIDE.md §Scope helper.
func MergeMobileScope ¶
func MergeMobileScope(plan, server *MobileScopeModel) *MobileScopeModel
MergeMobileScope overlays a declared iBeacon-bearing mobile scope onto the server's current scope. See MergeComputerScope for the contract.
func (MobileScopeModel) TargetsOrZero ¶
func (m MobileScopeModel) TargetsOrZero() MobileScopeTargetsModel
TargetsOrZero returns the targets sub-model, or a zero value with null sets when the block was omitted, so input-builders can read target fields without a nil-guard.
type MobileScopeModelNoIbeacons ¶
type MobileScopeModelNoIbeacons struct {
Targets *MobileScopeTargetsModel `tfsdk:"targets"`
Limitations *MobileScopeLimitationsModelNoIbeacons `tfsdk:"limitations"`
Exclusions *MobileScopeExclusionsModelNoIbeacons `tfsdk:"exclusions"`
}
MobileScopeModelNoIbeacons is the Terraform model for a mobile-device-scope <scope> block built with MobileScopeAttributes(IncludeIbeacons=false). The target fields are identical to MobileScopeModel; only the limitations and exclusions sub-blocks differ (no ibeacon_ids). The framework matches model fields to schema attributes exactly, so a no-iBeacon schema needs its own model rather than reusing MobileScopeModel (which carries IbeaconIDs).
Consumed by mobile_device_app, whose /mobiledeviceapplications endpoint omits iBeacon limitations/exclusions (wire-probed). See STYLE_GUIDE.md §Scope helper.
func MergeMobileScopeNoIbeacons ¶
func MergeMobileScopeNoIbeacons(plan, server *MobileScopeModelNoIbeacons) *MobileScopeModelNoIbeacons
MergeMobileScopeNoIbeacons is MergeMobileScope for the no-iBeacon model variant (mobile_device_app).
func (MobileScopeModelNoIbeacons) TargetsOrZero ¶
func (m MobileScopeModelNoIbeacons) TargetsOrZero() MobileScopeTargetsModel
TargetsOrZero returns the targets sub-model, or a zero value with null sets when the block was omitted. See MobileScopeModel.TargetsOrZero.
type MobileScopeOptions ¶
type MobileScopeOptions struct {
// IncludeIbeacons adds ibeacon_ids to the limitations and exclusions
// sub-blocks. Resources whose endpoint ignores iBeacon scope must leave
// this false so the attribute is absent rather than silently dropped.
IncludeIbeacons bool
}
MobileScopeOptions gates the handful of per-resource deltas in the otherwise-shared Jamf classic mobile-device-scope block. Today the only axis is iBeacon support: mobile_device_configuration_profile carries iBeacon limitations/exclusions; the mobiledeviceapplications endpoint omits them (wire-probed), so mobile_device_app sets IncludeIbeacons=false to avoid a permadiff. See STYLE_GUIDE.md §Scope helper.
type MobileScopeTargetsModel ¶
type MobileScopeTargetsModel struct {
AllMobileDevices types.Bool `tfsdk:"all_mobile_devices"`
AllJssUsers types.Bool `tfsdk:"all_jss_users"`
MobileDeviceIDs types.Set `tfsdk:"mobile_device_ids"`
MobileDeviceGroupIDs types.Set `tfsdk:"mobile_device_group_ids"`
BuildingIDs types.Set `tfsdk:"building_ids"`
DepartmentIDs types.Set `tfsdk:"department_ids"`
UserIDs types.Set `tfsdk:"user_ids"`
UserGroupIDs types.Set `tfsdk:"user_group_ids"`
}
MobileScopeTargetsModel models <scope> targets — the all-flags plus the per-category ID sets, mirroring the admin UI's Targets tab. Shared by both iBeacon variants (targets do not carry iBeacons).
type SecondaryEstate ¶
type SecondaryEstate struct {
DeviceType impact.DeviceType
DeviceAttr string
GroupAttr string
All types.Bool
DeviceIDs types.Set
GroupIDs types.Set
}
SecondaryEstate carries the second estate's device and group categories for a resource that targets both at once. An ebook is scoped to computers and mobile devices in the same block, and the two are counted together.
type UserScopeExclusionsModel ¶
type UserScopeExclusionsModel struct {
JssUserIDs types.Set `tfsdk:"jss_user_ids"`
JssUserGroupIDs types.Set `tfsdk:"jss_user_group_ids"`
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
UserScopeExclusionsModel models <scope><exclusions>. The UI exposes Users / User Groups (id-keyed Jamf objects) and Directory Service User Groups (name-keyed, wire-confirmed name-only).
type UserScopeLimitationsModel ¶
type UserScopeLimitationsModel struct {
DirectoryServiceUserGroupNames types.Set `tfsdk:"directory_service_user_group_names"`
}
UserScopeLimitationsModel models <scope><limitations>. The UI exposes only "Directory Service User Groups". These are NAME-keyed (wire-probed: PUT-by-id → 409, PUT-by-name → 201); the SDK's IDName item type is a superset and only its name is populated.
type UserScopeModel ¶
type UserScopeModel struct {
Targets *UserScopeTargetsModel `tfsdk:"targets"`
Limitations *UserScopeLimitationsModel `tfsdk:"limitations"`
Exclusions *UserScopeExclusionsModel `tfsdk:"exclusions"`
}
UserScopeModel is the Terraform model for a Jamf classic user-based <scope> block. Field names + tfsdk tags match UserScopeAttributes. This is the USER-BASED scope subset (a third scope shape distinct from computer/mobile): targets are Jamf Pro users / Jamf Pro user groups (id-keyed) plus the all_jss_users flag; limitations and exclusions carry directory-service (LDAP) user groups by NAME.
Write semantics (wire-probed): a scope PUT replaces the entire subtree once any category element is present, so per-category ownership is synthesised via read-merge-write — the resource's Update overlays declared categories onto the live server scope (MergeUserScope) and emits the full <scope> skeleton (empty elements clear). A nil *UserScopeModel omits <scope> entirely and leaves the server's scope untouched.
Consumed by vpp_invitation and vpp_assignment. The build/flatten glue stays per-resource because VppInvitation* and VppAssignment* are distinct generated SDK structs with no shared interface. See STYLE_GUIDE.md §Scope helper.
func MergeUserScope ¶
func MergeUserScope(plan, server *UserScopeModel) *UserScopeModel
MergeUserScope overlays a declared user-based scope (vpp_assignment / vpp_invitation) onto the server's current scope. See MergeComputerScope for the contract.
func (UserScopeModel) TargetsOrZero ¶
func (m UserScopeModel) TargetsOrZero() UserScopeTargetsModel
TargetsOrZero returns the targets sub-model, or a zero value with null fields when the block was omitted, so input-builders can read target fields without a nil-guard.
type UserScopeTargetsModel ¶
type UserScopeTargetsModel struct {
AllJssUsers types.Bool `tfsdk:"all_jss_users"`
JssUserIDs types.Set `tfsdk:"jss_user_ids"`
JssUserGroupIDs types.Set `tfsdk:"jss_user_group_ids"`
}
UserScopeTargetsModel models <scope> targets — the all_jss_users flag plus the Jamf Pro user / user-group ID sets, mirroring the admin UI's Targets tab.