Documentation
¶
Overview ¶
Package patch_software_title implements the jamfplatform_pro_patch_software_title resource, data source, and list resource backed by the Jamf Pro v3 patch-software-title-configurations API, plus the one classic /patchsoftwaretitles call that mints a title's id (see crud.go header).
Index ¶
- func NewPatchSoftwareTitleDataSource() datasource.DataSource
- func NewPatchSoftwareTitleListResource() list.ListResource
- func NewPatchSoftwareTitleResource() resource.Resource
- type PatchSoftwareTitleDataSource
- func (d *PatchSoftwareTitleDataSource) ConfigValidators(ctx context.Context) []datasource.ConfigValidator
- func (d *PatchSoftwareTitleDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, ...)
- func (d *PatchSoftwareTitleDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, ...)
- func (d *PatchSoftwareTitleDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse)
- func (d *PatchSoftwareTitleDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, ...)
- type PatchSoftwareTitleDataSourceModel
- type PatchSoftwareTitleEAModel
- type PatchSoftwareTitleListResource
- func (r *PatchSoftwareTitleListResource) Configure(ctx context.Context, req resource.ConfigureRequest, ...)
- func (r *PatchSoftwareTitleListResource) List(ctx context.Context, req list.ListRequest, stream *list.ListResultsStream)
- func (r *PatchSoftwareTitleListResource) ListResourceConfigSchema(ctx context.Context, req list.ListResourceSchemaRequest, ...)
- func (r *PatchSoftwareTitleListResource) Metadata(ctx context.Context, req resource.MetadataRequest, ...)
- type PatchSoftwareTitleListResourceModel
- type PatchSoftwareTitleResource
- func (r *PatchSoftwareTitleResource) Configure(ctx context.Context, req resource.ConfigureRequest, ...)
- func (r *PatchSoftwareTitleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
- func (r *PatchSoftwareTitleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse)
- func (r *PatchSoftwareTitleResource) IdentitySchema(ctx context.Context, req resource.IdentitySchemaRequest, ...)
- func (r *PatchSoftwareTitleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, ...)
- func (r *PatchSoftwareTitleResource) Metadata(ctx context.Context, req resource.MetadataRequest, ...)
- func (r *PatchSoftwareTitleResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, ...)
- func (r *PatchSoftwareTitleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse)
- func (r *PatchSoftwareTitleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse)
- func (r *PatchSoftwareTitleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse)
- func (r *PatchSoftwareTitleResource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader
- type PatchSoftwareTitleResourceModel
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewPatchSoftwareTitleDataSource ¶
func NewPatchSoftwareTitleDataSource() datasource.DataSource
NewPatchSoftwareTitleDataSource returns a new instance of PatchSoftwareTitleDataSource.
func NewPatchSoftwareTitleListResource ¶
func NewPatchSoftwareTitleListResource() list.ListResource
NewPatchSoftwareTitleListResource returns a list resource for Jamf Pro patch software title queries.
func NewPatchSoftwareTitleResource ¶
NewPatchSoftwareTitleResource returns a new instance of PatchSoftwareTitleResource.
Types ¶
type PatchSoftwareTitleDataSource ¶
type PatchSoftwareTitleDataSource struct {
// contains filtered or unexported fields
}
PatchSoftwareTitleDataSource implements the Terraform data source for Jamf Pro patch software titles. Lookup is by ID or by exact display name — exactly one of the two must be supplied. The full server view is surfaced, including every assigned version→package pair.
source_id is resolved, not read: the v3 configuration names a title's patch source but never numbers it, and a data source has no prior state to carry the number in. The resolution is best-effort — source_id comes back null with a warning when the name matches no patch source, matches one in both catalogues, or the catalogues cannot be read — because the attribute is Computed and informational here, unlike the managed resource where it defines the title. It goes through the provider-instance catalogue cache so a configuration of many titles reads the catalogues once, not twice per title.
func (*PatchSoftwareTitleDataSource) ConfigValidators ¶
func (d *PatchSoftwareTitleDataSource) ConfigValidators(ctx context.Context) []datasource.ConfigValidator
ConfigValidators enforces that exactly one of id / name is supplied.
func (*PatchSoftwareTitleDataSource) Configure ¶
func (d *PatchSoftwareTitleDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse)
Configure wires the Pro client used for the v3 configuration reads, plus the shared patch source catalogue cache source_id resolves through.
func (*PatchSoftwareTitleDataSource) Metadata ¶
func (d *PatchSoftwareTitleDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse)
Metadata sets the data source type name for the Terraform provider.
func (*PatchSoftwareTitleDataSource) Read ¶
func (d *PatchSoftwareTitleDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse)
Read fetches a patch software title by ID and populates Terraform state.
func (*PatchSoftwareTitleDataSource) Schema ¶
func (d *PatchSoftwareTitleDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse)
Schema returns the data source schema. id is the sole selector; the remaining attributes are populated from the SDK response.
type PatchSoftwareTitleDataSourceModel ¶
type PatchSoftwareTitleDataSourceModel struct {
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
NameID types.String `tfsdk:"name_id"`
SoftwareTitleName types.String `tfsdk:"software_title_name"`
SourceID types.Int64 `tfsdk:"source_id"`
CategoryID types.String `tfsdk:"category_id"`
SiteID types.String `tfsdk:"site_id"`
WebNotification types.Bool `tfsdk:"web_notification"`
EmailNotification types.Bool `tfsdk:"email_notification"`
VersionPackages types.Map `tfsdk:"version_packages"`
AvailableVersions types.List `tfsdk:"available_versions"`
KillApps types.List `tfsdk:"kill_apps"`
Timeouts datasourceTimeouts.Value `tfsdk:"timeouts"`
}
PatchSoftwareTitleDataSourceModel represents the Terraform data source model. Lookup is by ID or by exact display name — exactly one of the two must be supplied. See data_source.go (lookupByName).
SourceID is not read but resolved, from the patch source name the payload reports, and the resolution is best-effort: it is null with a warning whenever the name cannot be matched to exactly one patch source, including when the source catalogues cannot be read at all (see sourceIDFromCatalogues). The managed resource is the one construct where an unresolved name is fatal, on import, because there SourceID defines the title and forces replacement.
type PatchSoftwareTitleEAModel ¶
type PatchSoftwareTitleEAModel struct {
EaID types.String `tfsdk:"ea_id"`
DisplayName types.String `tfsdk:"display_name"`
Accepted types.Bool `tfsdk:"accepted"`
}
PatchSoftwareTitleEAModel is one Jamf-defined extension attribute attached to a patch software title. For some titles, Jamf creates an EA that collects the installed version on managed computers; it must be accepted before inventory is gathered. The list is read-only state (the catalog of EAs and their accept status); set accept_extension_attributes to accept any pending ones.
ExtensionAttributes is modelled as types.List (not []PatchSoftwareTitleEAModel) because it is a Computed attribute with no plan modifier: it plans as Unknown, and a plain Go slice cannot represent an unknown value (Plan.Get would fail with "the target type cannot handle unknown values"). This struct is the element type used when converting to/from that list.
type PatchSoftwareTitleListResource ¶
type PatchSoftwareTitleListResource struct {
// contains filtered or unexported fields
}
PatchSoftwareTitleListResource implements Terraform query list support. The v3 configurations list accepts no query parameters, so the optional `filter` block is applied client-side via filters.ApplyClassicFilter after the full list is fetched.
source_id is resolved, not read: the v3 configuration names a title's patch source but never numbers it. The resolution goes through the shared provider-instance catalogue cache, so a list pays the two catalogue reads once however many titles it returns, and it is best-effort — see List.
func (*PatchSoftwareTitleListResource) Configure ¶
func (r *PatchSoftwareTitleListResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse)
Configure wires the Pro client used for the v3 configurations list, plus the shared patch source catalogue cache source_id resolves through.
func (*PatchSoftwareTitleListResource) List ¶
func (r *PatchSoftwareTitleListResource) List(ctx context.Context, req list.ListRequest, stream *list.ListResultsStream)
List executes the query and streams patch software title identities back to Terraform.
The v3 configurations list returns whole configuration objects rather than stubs, so include_resource hydrates everything that payload carries. Two attributes stay null because filling them would cost a call per item: available_versions, which lives on the /definitions sub-resource, and extension_attributes, whose display names come from the /extension-attributes sub-resource (the configuration body carries only ids and accept flags). A list preview does not require full hydration — consumers needing those should use the singular data source or the managed resource.
source_id is not on the payload either. The provider tries to resolve it from the patch source name, out of two small tenant-wide catalogues read once for the whole list, but the attempt can fail without the list failing: a name present in both catalogues cannot be resolved at all, a source renamed or removed since the title was created matches neither, and the catalogues need privileges of their own. Every one of those leaves that title's source_id null and attaches a warning naming the title — a preview reports what it could not determine rather than dropping it, and rather than failing the whole listing over an informational attribute.
version_packages goes through assignedVersionPackagesValue rather than a direct fold, because a title with no assignments must land as an unset attribute: an empty map is not a legal configuration value, so emitting one would hand `terraform plan -generate-config-out` configuration this provider then refuses.
func (*PatchSoftwareTitleListResource) ListResourceConfigSchema ¶
func (r *PatchSoftwareTitleListResource) ListResourceConfigSchema(ctx context.Context, req list.ListResourceSchemaRequest, resp *list.ListResourceSchemaResponse)
ListResourceConfigSchema describes the supported list filters.
func (*PatchSoftwareTitleListResource) Metadata ¶
func (r *PatchSoftwareTitleListResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse)
Metadata sets the list resource type name.
type PatchSoftwareTitleListResourceModel ¶
type PatchSoftwareTitleListResourceModel struct {
Filter *filters.ClassicFilterModel `tfsdk:"filter"`
Timeouts listtimeouts.Value `tfsdk:"timeouts"`
}
PatchSoftwareTitleListResourceModel represents the config model for list queries. The v3 configurations list takes no query parameters, so the filter shape is the shared client-side substring block, matching each title's display name.
type PatchSoftwareTitleResource ¶
type PatchSoftwareTitleResource struct {
// contains filtered or unexported fields
}
PatchSoftwareTitleResource implements the Terraform resource for Jamf Pro patch software titles. Read, update, delete and the extension-attribute side-channel run over the v3 /patch-software-title-configurations endpoints (proClient). The classic client is needed for two things only: the POST that mints a title's id, which v3 has no equivalent for, and resolving a patch source's name back to the source_id v3 omits. Both keys are the same number — the classic title id equals the configuration id, wire-verified.
func (*PatchSoftwareTitleResource) Configure ¶
func (r *PatchSoftwareTitleResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse)
Configure wires both Jamf clients into the resource: the Pro client (the v3 configuration CRUD and extension-attribute side-channel) and the ProClassic client (the id-minting create and patch-source name resolution). Both are built from the same provider data.
func (*PatchSoftwareTitleResource) Create ¶
func (r *PatchSoftwareTitleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
Create mints a new patch software title then applies metadata + package assignments. The classic POST to id="0" allocates the real ID and seeds the full versions catalog from the patch definition (name_id + source_id define the title), creating the v3 configuration in the same act. category/site/notifications/version_packages are then applied through a single v3 merge-patch, which answers with the stored configuration.
The version catalogue read that follows is best-effort. The title is minted by then, so a fatal catalogue failure would return before the only State.Set and orphan it server-side — the next apply would re-POST the same name_id + source_id. It therefore warns and leaves available_versions empty, which the next Read fills in; the same line the accept side-call sits behind, one screen lower.
func (*PatchSoftwareTitleResource) Delete ¶
func (r *PatchSoftwareTitleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse)
Delete removes a Jamf Pro patch software title. Deleting the v3 configuration removes the classic title with it — wire-probed 2026-09-02: the DELETE answers 204 and the classic GET then answers 404, so no classic-side object is left behind.
func (*PatchSoftwareTitleResource) IdentitySchema ¶
func (r *PatchSoftwareTitleResource) IdentitySchema(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse)
IdentitySchema defines the identifier used for import and list results.
func (*PatchSoftwareTitleResource) ImportState ¶
func (r *PatchSoftwareTitleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse)
ImportState handles import by the Jamf Pro patch software title ID.
func (*PatchSoftwareTitleResource) Metadata ¶
func (r *PatchSoftwareTitleResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse)
Metadata sets the resource type name for the Terraform provider.
func (*PatchSoftwareTitleResource) ModifyPlan ¶ added in v1.7.0
func (r *PatchSoftwareTitleResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse)
ModifyPlan reports a title that another configuration already defines for the same patch source and site.
func (*PatchSoftwareTitleResource) Read ¶
func (r *PatchSoftwareTitleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse)
Read refreshes state. version_packages is rebuilt from only the keys recorded in prior state, the managed subset — including on a first-time hydration, which declares nothing and so adopts no assignments (see managedVersionPackages for why an import must not).
source_id, which the v3 payload does not carry, is resolved from the reported patch source name on that same hydration path. It backs a Required, RequiresReplace attribute, so Create and Update always populate it before any Read and it can only be unset here on a first-time hydration — which makes it the signal, since assignPatchSoftwareTitleResourceModel never touches it. A failure resolving it is fatal rather than a warning, because a wrong or absent value shows up as a plan that destroys the freshly imported title.
The version catalogue read is best-effort here too: a title whose configuration reads cleanly should not take a whole plan down because a supplementary catalogue read failed, which is the line refreshExtensionAttributes already draws. The prior state's available_versions is carried through on failure, so a warning never rewrites the attribute to an empty list and claims the title publishes no versions.
func (*PatchSoftwareTitleResource) Schema ¶
func (r *PatchSoftwareTitleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse)
Schema returns the Terraform schema for the patch software title resource.
func (*PatchSoftwareTitleResource) Update ¶
func (r *PatchSoftwareTitleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse)
Update applies metadata + package changes through a single v3 merge-patch, which answers with the stored configuration.
Because the v3 `packages` array is a full replacement, the desired assignments are folded over the server's live set so that assignments made outside Terraform survive — the managed-subset contract version_packages documents. That fold needs the live set, so it costs a read; when neither the plan nor prior state declares any assignment there is nothing to manage and the key is omitted instead, skipping the read. An assignment the provider cannot read back (no version or no package id) cannot be folded in, and a full replacement clears whatever it omits, so how many of those an apply is about to clear is warned about rather than passed over in silence.
The version catalogue read after the patch is best-effort, and falls back to the PRIOR STATE's available_versions rather than the plan's: the attribute is plain Computed with no plan modifier, so the planned value is Unknown here and an apply must still write something known or Terraform reports an inconsistent result. Erroring instead would discard a merge-patch that already succeeded, leaving the pre-apply name, category, site, notifications and package assignments in state.
func (*PatchSoftwareTitleResource) UpgradeState ¶
func (r *PatchSoftwareTitleResource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader
UpgradeState migrates prior state versions to the current schema.
v0 → v1: category_name and site_name were removed when read/update/delete moved from the classic /patchsoftwaretitles endpoints to Jamf Pro v3 /patch-software-title-configurations, which does not report them. The framework cannot decode prior state carrying attributes the current schema has no home for, so the keys are stripped from the raw prior state JSON and the remainder re-emitted through the current schema type. Every other attribute is carried across verbatim as raw JSON, so no value is reinterpreted or lost.
type PatchSoftwareTitleResourceModel ¶
type PatchSoftwareTitleResourceModel struct {
ID types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
NameID types.String `tfsdk:"name_id"`
SoftwareTitleName types.String `tfsdk:"software_title_name"`
SourceID types.Int64 `tfsdk:"source_id"`
CategoryID types.String `tfsdk:"category_id"`
SiteID types.String `tfsdk:"site_id"`
WebNotification types.Bool `tfsdk:"web_notification"`
EmailNotification types.Bool `tfsdk:"email_notification"`
VersionPackages types.Map `tfsdk:"version_packages"`
AvailableVersions types.List `tfsdk:"available_versions"`
AcceptExtensionAttributes types.Bool `tfsdk:"accept_extension_attributes"`
ExtensionAttributes types.List `tfsdk:"extension_attributes"`
Timeouts resourceTimeouts.Value `tfsdk:"timeouts"`
}
PatchSoftwareTitleResourceModel represents the Terraform resource model for a Jamf Pro patch software title.
VersionPackages is a managed-subset map keyed by software_version with package_id string values. The user only declares the version→package assignments they care about; the server holds the full catalog of versions (20+) for the title. Read reconciles only the keys the user declared, and Update folds them over the server's live set, so an assignment made outside Terraform survives an apply (see state_builders.go, input_builders.go).