scriptprovider

package
v0.1.0-beta.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: MIT Imports: 42 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(version string) func() provider.Provider

New returns a factory function for creating the provider.

func NewScriptDataSource

func NewScriptDataSource() datasource.DataSource

NewScriptDataSource is the constructor Terraform calls (via the provider's DataSources list) to create a fresh data source instance.

func NewScriptResource

func NewScriptResource() resource.Resource

NewScriptResource is the constructor Terraform calls (via the provider's Resources list) to create a fresh resource instance.

func Serve

func Serve(ctx context.Context, def Definition) error

Serve loads the definition and serves the provider until Terraform closes the plugin, then tears down every provider instance (running shutdown scripts and stopping sidecars). It blocks; load errors and serve errors are returned.

Types

type AttrSpec

type AttrSpec struct {
	Type            string          `json:"type"`
	ElementType     string          `json:"element_type"`
	Required        bool            `json:"required"`
	Optional        bool            `json:"optional"`
	Computed        bool            `json:"computed"`
	Sensitive       bool            `json:"sensitive"`
	Description     string          `json:"description"`
	RequiresReplace bool            `json:"requires_replace"`
	Default         json.RawMessage `json:"default"`
	Validators      []ValidatorSpec `json:"validators"`
	Env             string          `json:"env"`
	// contains filtered or unexported fields
}

AttrSpec is one attribute declaration inside a manifest.

type DataSourceDefinition

type DataSourceDefinition struct {
	Name       string
	Manifest   *Manifest
	Schema     dschema.Schema
	ReadScript string
	Timeout    time.Duration
}

DataSourceDefinition is one discovered provider/data-sources/<name>/ folder.

type Definition

type Definition struct {
	Settings Settings
	Version  string // stamped at build time via -ldflags "-X main.version=..."
	FS       fs.FS  // tree containing "provider/..." (typically an embed.FS)
	Debug    bool   // run with debugger support (managed by the fork's main.go flag)
}

Definition is everything needed to serve a derived provider: its identity, version, and the embedded filesystem containing the provider/ tree (settings, lifecycle scripts, resource and data-source folders).

type Factory

type Factory struct {
	// contains filtered or unexported fields
}

Factory creates provider instances while tracking them, so their persistent PowerShell processes (and shutdown scripts) can be cleanly torn down when the provider server stops. The terraform-plugin-framework offers no provider-level teardown callback, so the serving entrypoint must call Shutdown itself.

func NewFactory

func NewFactory(version string) *Factory

NewFactory returns a Factory that builds generic powershell providers reporting the given version.

func NewFactoryWith

func NewFactoryWith(newProvider func() ShutdownProvider) *Factory

NewFactoryWith returns a Factory that builds and tracks instances produced by the given constructor. Used by definition-based (derived) providers, which construct a different provider type but need the same teardown tracking.

func NewProviderFactory

func NewProviderFactory(def Definition) (func() provider.Provider, *Factory, error)

NewProviderFactory loads and validates the definition eagerly (bad manifests or missing scripts fail here, not at first use) and returns a provider constructor plus the tracking Factory whose Shutdown tears down every instance. Intended for Serve and for acceptance tests via providerserver.NewProtocol6WithError.

func (*Factory) New

func (f *Factory) New() func() provider.Provider

New returns a provider factory function suitable for providerserver.Serve. Every instance it creates is tracked for later Shutdown.

func (*Factory) Shutdown

func (f *Factory) Shutdown(ctx context.Context)

Shutdown tears down every provider instance the factory created, running each one's shutdown script exactly once.

type Manifest

type Manifest struct {
	// Schema is the editor's JSON Schema pointer (the "$schema" key). It
	// carries no provider semantics and is never read after decoding; it is
	// declared only so that strict decoding accepts it. See
	// https://json.schemastore.org/tfpowershell-resource.json and siblings.
	Schema string `json:"$schema"`

	Version        int                  `json:"version"`
	Description    string               `json:"description"`
	TimeoutSeconds int64                `json:"timeout_seconds"`
	Attributes     map[string]*AttrSpec `json:"attributes"`
}

Manifest is a parsed resource.tfps.json, datasource.tfps.json, or provider.tfps.json. One format serves all three; parseManifest enforces the per-context restrictions.

type PSCommand

type PSCommand struct {
	Action       string                 `json:"action"`                  // configure | create | read | update | delete | startup | shutdown
	Script       string                 `json:"script"`                  // the PowerShell scriptblock to run
	InputData    map[string]interface{} `json:"input_data"`              // passed to the script as the bound $InputData parameter
	ProviderData map[string]interface{} `json:"provider_data,omitempty"` // connection args exposed to scripts as $global:ProviderData (configure only)
	Session      *PSSessionConfig       `json:"session,omitempty"`       // optional remote-session details (configure only)
}

PSCommand is the JSON request sent to the PowerShell process for one action. ProviderData and Session are only populated on the one-time "configure" command the provider sends before the startup script.

type PSManager

type PSManager struct {
	// contains filtered or unexported fields
}

PSManager manages the lifecycle of a persistent PowerShell process and provides thread-safe command execution via stdin/stdout JSON protocol.

func NewPSManager

func NewPSManager(ctx context.Context, defaultTimeout time.Duration) (*PSManager, error)

NewPSManager starts the pshost sidecar process running the PowerShell responder loop.

func (*PSManager) Close

func (m *PSManager) Close() error

Close runs the registered shutdown script (if any) and then shuts down the PowerShell process gracefully. It is idempotent and safe to call multiple times: the shutdown script and teardown run only on the first call.

func (*PSManager) Configure

func (m *PSManager) Configure(providerData map[string]interface{}, session *PSSessionConfig, timeout time.Duration) error

Configure sends the one-time "configure" command, which seeds $global:ProviderData and, when session details are supplied, opens the remote PowerShell session that every subsequent script runs in. The provider calls this once, before the startup script, so connection details and provider arguments are in place first.

func (*PSManager) Execute

func (m *PSManager) Execute(action, script string, inputData map[string]interface{}, timeout time.Duration) (*PSResponse, error)

Execute sends a CRUD/lifecycle command to the PowerShell process and returns the response. It is safe to call from multiple goroutines; a mutex serializes access.

func (*PSManager) SetShutdownScript

func (m *PSManager) SetShutdownScript(script string, timeout time.Duration)

SetShutdownScript registers a script that Close runs exactly once, in the same persistent PowerShell process, just before the process is terminated. Because it shares the process (and remote session, if any) with every resource operation, it can observe any globals accumulated during the run. Calling it more than once appends: Close runs every registered script in registration order.

type PSResponse

type PSResponse struct {
	Success    bool                   `json:"success"`     // false if the script threw or wrote to the error stream
	OutputData map[string]interface{} `json:"output_data"` // the single object the script emitted to the output stream
	Error      string                 `json:"error"`       // error message when Success is false
}

PSResponse is the JSON reply received from the PowerShell process after an action.

type PSSessionConfig

type PSSessionConfig struct {
	Type              string `json:"type"`                         // winrm | ssh | vmguest
	Host              string `json:"host,omitempty"`               // remote computer / hostname (winrm, ssh)
	Port              int64  `json:"port,omitempty"`               // optional port override
	Username          string `json:"username,omitempty"`           // session credential user
	Password          string `json:"password,omitempty"`           // session credential password
	UseSSL            bool   `json:"use_ssl,omitempty"`            // winrm: connect over HTTPS
	Authentication    string `json:"authentication,omitempty"`     // winrm: Default/Basic/Negotiate/Kerberos/Credssp/...
	CertThumbprint    string `json:"cert_thumbprint,omitempty"`    // winrm: client-certificate auth thumbprint
	ConfigurationName string `json:"configuration_name,omitempty"` // winrm: session configuration endpoint
	KeyFile           string `json:"key_file,omitempty"`           // ssh: private key file path
	VMName            string `json:"vm_name,omitempty"`            // vmguest: VM name (PowerShell Direct)
	VMId              string `json:"vm_id,omitempty"`              // vmguest: VM GUID (PowerShell Direct)
}

PSSessionConfig describes an optional remote PowerShell session for the host to open (modeling New-PSSession / Enter-PSSession). When present on the configure command, every subsequent script runs in that remote runspace. Field names are kept in sync with the SessionConfig class in csharp/PSHost/RunspaceManager.cs.

type PowerShellProvider

type PowerShellProvider struct {
	// contains filtered or unexported fields
}

PowerShellProvider implements the Terraform provider for PowerShell script execution. A single instance owns one persistent PowerShell process (via psManager) that lives for the whole Terraform run, so every resource operation shares the same interpreter and global state.

func (*PowerShellProvider) Configure

Configure is called once, before any resource operation. It decodes the provider configuration, starts the persistent PowerShell process, runs the optional startup script, and registers the optional shutdown script. The resulting PSManager is handed to every resource via resp.ResourceData.

func (*PowerShellProvider) DataSources

func (p *PowerShellProvider) DataSources(_ context.Context) []func() datasource.DataSource

DataSources lists the data sources this provider implements.

func (*PowerShellProvider) Metadata

Metadata reports the provider's type name and version to Terraform. The type name ("powershell") becomes the prefix for every resource this provider exposes, e.g. the script resource is addressed as "powershell_script".

func (*PowerShellProvider) Resources

func (p *PowerShellProvider) Resources(_ context.Context) []func() resource.Resource

Resources lists the resource types this provider implements. Terraform calls each constructor to instantiate a resource when one appears in configuration.

func (*PowerShellProvider) Schema

Schema declares the attributes accepted in the provider block. Terraform uses this both to validate user configuration and to render documentation.

func (*PowerShellProvider) Shutdown

func (p *PowerShellProvider) Shutdown(_ context.Context) error

Shutdown runs the registered shutdown script (if any) and terminates the persistent PowerShell process. It is safe to call multiple times; the shutdown script runs at most once. Serving must invoke this when it stops (see Factory and main) because the plugin framework has no teardown hook.

func (*PowerShellProvider) ValidateConfig

ValidateConfig enforces the cross-attribute rules of the session_* arguments at plan time, so misconfigurations fail fast with a pointed message instead of surfacing as a New-PSSession error from inside the PowerShell host.

type PowerShellProviderModel

type PowerShellProviderModel struct {
	StartupScript  types.String `tfsdk:"startup_script"`
	ShutdownScript types.String `tfsdk:"shutdown_script"`
	Timeout        types.Int64  `tfsdk:"timeout"`

	// Connection arguments. All optional; surfaced to every script as the
	// $global:ProviderData hashtable.
	Server                types.String `tfsdk:"server"`
	Username              types.String `tfsdk:"username"`
	Password              types.String `tfsdk:"password"`
	CertThumbprint        types.String `tfsdk:"cert_thumbprint"`
	ProviderData          types.String `tfsdk:"provider_data"`
	SensitiveProviderData types.String `tfsdk:"sensitive_provider_data"`

	// Remote session arguments (session_*). When session_type is set the host
	// connects to the remote computer first and runs every script there.
	SessionType              types.String `tfsdk:"session_type"`
	SessionHost              types.String `tfsdk:"session_host"`
	SessionPort              types.Int64  `tfsdk:"session_port"`
	SessionUsername          types.String `tfsdk:"session_username"`
	SessionPassword          types.String `tfsdk:"session_password"`
	SessionUseSSL            types.Bool   `tfsdk:"session_use_ssl"`
	SessionAuthentication    types.String `tfsdk:"session_authentication"`
	SessionCertThumbprint    types.String `tfsdk:"session_cert_thumbprint"`
	SessionConfigurationName types.String `tfsdk:"session_configuration_name"`
	SessionKeyFile           types.String `tfsdk:"session_key_file"`
	SessionVMName            types.String `tfsdk:"session_vm_name"`
	SessionVMId              types.String `tfsdk:"session_vm_id"`
}

PowerShellProviderModel maps the provider block's HCL attributes onto Go fields. The `tfsdk` tags must match the attribute names declared in Schema; the framework uses them to decode the user's configuration into this struct.

type ResourceDefinition

type ResourceDefinition struct {
	Name     string // directory name; Terraform type is <provider>_<Name>
	Manifest *Manifest
	Schema   rschema.Schema
	Scripts  ScriptSet
	Timeout  time.Duration // from timeout_seconds; 0 means provider default
}

ResourceDefinition is one discovered provider/resources/<name>/ folder, parsed and schema-built at load time.

type ScriptDataSource

type ScriptDataSource struct {
	// contains filtered or unexported fields
}

ScriptDataSource implements the powershell_script data source: a read-only script executed during refresh, analogous to the hashicorp/external data source. It runs in the same persistent PowerShell process (and remote session, if any) as every resource, so it can use provider-level globals.

func (*ScriptDataSource) Configure

Configure receives the configured provider (set as resp.DataSourceData in the provider's Configure) and stores it so Read can use its psManager.

func (*ScriptDataSource) Metadata

Metadata sets the data source's type name by combining the provider prefix with "_script", yielding "powershell_script".

func (*ScriptDataSource) Read

Read executes the script and records its output. Unlike the resource's Read, empty output is not "resource gone" — it simply yields empty output_data.

func (*ScriptDataSource) Schema

Schema declares the attributes of the powershell_script data source.

type ScriptDataSourceModel

type ScriptDataSourceModel struct {
	Script              types.String `tfsdk:"script"`
	InputData           types.String `tfsdk:"input_data"`
	SensitiveInputData  types.String `tfsdk:"sensitive_input_data"`
	OutputData          types.String `tfsdk:"output_data"`
	SensitiveOutputData types.String `tfsdk:"sensitive_output_data"`
	Timeout             types.Int64  `tfsdk:"timeout"`
}

ScriptDataSourceModel maps the data block's HCL attributes onto Go fields.

type ScriptResource

type ScriptResource struct {
	// contains filtered or unexported fields
}

ScriptResource implements the powershell_script Terraform resource. It holds a back-reference to the provider so it can reach the shared psManager and run its CRUD scripts in the same persistent PowerShell process as every other resource.

func (*ScriptResource) Configure

Configure receives the configured provider (set as resp.ResourceData in the provider's Configure) and stores it so CRUD methods can use its psManager.

func (*ScriptResource) Create

Create runs the create_script, requires it to return an id, and records the returned id and output in Terraform state.

func (*ScriptResource) Delete

Delete runs the delete_script to destroy the resource. On success the framework drops the resource from state automatically; no state is written.

func (*ScriptResource) ImportState

ImportState supports `terraform import` by taking the supplied id string and writing it to the resource's id attribute. A subsequent Read then populates the rest of the state from the read_script.

func (*ScriptResource) Metadata

Metadata sets the resource's type name by combining the provider prefix with "_script", yielding "powershell_script".

func (*ScriptResource) ModifyPlan

ModifyPlan implements the update-vs-replace semantics:

  • without an update_script, input changes can only be realized by replacing the resource (delete then create);
  • with an update_script, input changes run it in place, so the computed outputs are unknowable at plan time and must be marked unknown (otherwise Terraform errors when the applied outputs differ from prior state).

func (*ScriptResource) Read

Read runs the read_script to refresh the resource's current state. If the script reports the resource is gone (empty output or missing id), the resource is removed from state so Terraform will plan to recreate it.

func (*ScriptResource) Schema

Schema declares the attributes of a powershell_script resource and how they behave during planning (e.g. which changes force a replacement).

func (*ScriptResource) Update

Update runs the update_script for in-place input changes. Updates that change only config metadata (scripts, timeout) execute nothing and simply persist the new config, carrying the previous outputs forward. The id is computed (never in the plan), so it is copied over from prior state before the script runs.

type ScriptResourceModel

type ScriptResourceModel struct {
	ID                  types.String `tfsdk:"id"`
	CreateScript        types.String `tfsdk:"create_script"`
	ReadScript          types.String `tfsdk:"read_script"`
	UpdateScript        types.String `tfsdk:"update_script"`
	DeleteScript        types.String `tfsdk:"delete_script"`
	InputData           types.String `tfsdk:"input_data"`
	SensitiveInputData  types.String `tfsdk:"sensitive_input_data"`
	OutputData          types.String `tfsdk:"output_data"`
	SensitiveOutputData types.String `tfsdk:"sensitive_output_data"`
	Triggers            types.Map    `tfsdk:"triggers"`
	Timeout             types.Int64  `tfsdk:"timeout"`
}

ScriptResourceModel maps the resource block's HCL attributes onto Go fields. The `tfsdk` tags must match the attribute names declared in Schema.

type ScriptSet

type ScriptSet struct {
	Create string
	Read   string
	Update string
	Delete string
}

ScriptSet holds the CRUD script contents for one resource. Update == "" means the resource has no update.ps1: any config change forces replacement.

type Settings

type Settings struct {
	// Name is the provider type name, e.g. "exchangeonlinemanagement". It
	// prefixes every resource and data source type.
	Name string `json:"name"`
	// Address is the registry source address practitioners put in
	// required_providers, e.g. "registry.terraform.io/acme/exchangeonlinemanagement".
	Address string `json:"address"`
}

Settings identifies a definition-based (derived) provider. It is authored by the fork as provider/settings.tfps.json and read from the embedded filesystem.

func LoadSettings

func LoadSettings(fsys fs.FS) (Settings, error)

LoadSettings reads and validates provider/settings.tfps.json from the given filesystem. The fork's managed main.go uses this so the identity lives in exactly one user-owned file.

type ShutdownProvider

type ShutdownProvider interface {
	provider.Provider
	Shutdown(context.Context) error
}

ShutdownProvider is a provider whose persistent PowerShell process (and registered shutdown scripts) can be torn down after serving stops. Both the generic PowerShellProvider and definition-based providers implement it.

type ValidatorSpec

type ValidatorSpec struct {
	OneOf []interface{} `json:"one_of"`
}

ValidatorSpec is one entry of an attribute's "validators" array. Each entry is an object with exactly one recognized key; unknown keys are load errors, which keeps the format forward-extensible without silent misbehavior.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL