Help us shape the future of Go! Take the 2026 Go Developer Survey

multienv

package
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Quiet bool

Quiet suppresses progress messages.

Functions

func RunPipeline

func RunPipeline(opts *Options) error

RunPipeline orchestrates the multi-environment export:

  1. Run discovery + terraform plan for each environment (into temp dirs)
  2. Match resources across environments by (type, label)
  3. Postprocess the source-of-truth environment's output
  4. Extract support files for all environments
  5. Classify support files as shared vs divergent
  6. Assemble module directory and split partial-env resources
  7. Diff attributes and extract differences to variables
  8. Generate module variables
  9. Generate per-environment root directories
  10. Cleanup and format

Types

type AttrDiff

type AttrDiff struct {
	ResourceType string            // e.g. "jamfpro_policy"
	Label        string            // e.g. "install_rosetta"
	AttrName     string            // e.g. "priority"
	Values       map[string]string // env name → attribute value expression
	VarName      string            // generated variable name
	VarType      string            // HCL variable type, e.g. "string", "list(string)"
}

AttrDiff represents an attribute whose value differs across environments.

func DiffResources

func DiffResources(moduleDir string, envResults map[string]*PerEnvResult, matches []MatchedResource, sourceEnv string) ([]AttrDiff, error)

DiffResources compares generated HCL across environments for matched resources and identifies attributes that differ. Differing attributes are replaced with variable references in the module .tf files and the per-env values are returned. moduleDir is the directory containing postprocessed resource .tf files (e.g. output/modules/jamf/).

type ClassifiedFile

type ClassifiedFile struct {
	// RelPath is the path relative to the support_files/<env>/ directory,
	// e.g. "scripts/install_agent.sh"
	RelPath string

	// Class indicates whether the file is shared or divergent.
	Class SupportFileClass
}

ClassifiedFile holds the classification result for a single support file.

type EnvConfig

type EnvConfig struct {
	Name         string // e.g. "dev", "staging", "prod"
	URL          string // Jamf Pro instance URL, or Jamf Platform base_url
	AuthMethod   string // "basic" or "oauth2" (Jamf Platform is always "oauth2")
	Username     string
	Password     string
	ClientID     string
	ClientSecret string
	// EnvironmentID and TenantID are the two Jamf Platform scope identifiers,
	// mutually exclusive. Both empty is organization scope. Ignored by the
	// jamfpro provider, which has no notion of either.
	EnvironmentID string
	TenantID      string
}

EnvConfig holds credentials and URL for a single Jamf environment.

func (EnvConfig) PlatformScope added in v0.6.0

func (e EnvConfig) PlatformScope() platform.Scope

PlatformScope resolves this environment's Jamf Platform scope.

type MatchedResource

type MatchedResource struct {
	ResourceType string
	Label        string
	Name         string            // human-readable Jamf name
	IDs          map[string]string // env name → Jamf ID
	Present      []string          // which envs have this resource
	AllEnvs      bool              // true if present in every environment
}

MatchedResource represents a resource found across multiple environments.

func MatchResources

func MatchResources(envResults map[string]*PerEnvResult, envNames []string) []MatchedResource

MatchResources matches resources across environments by (resource_type, label). Labels are derived from Jamf object names via naming.Sanitize(), so instances with the same resource names produce matching labels.

type ModuleVar

type ModuleVar struct {
	Name         string // variable name, e.g. "script_install_agent_contents"
	Description  string // human-readable description
	ResourceType string // e.g. "jamfpro_script"
	Label        string // e.g. "install_agent"
	AttrName     string // e.g. "script_contents"
	FilePath     string // relative path to the divergent file, e.g. "scripts/install_agent.sh"
	Sensitive    bool   // mark the declared variable sensitive (write-only secrets)
	Type         string // declared HCL type; empty means "string"
}

ModuleVar represents a variable that the module declares and each environment's main.tf supplies. It covers divergent support file content, file(var.X) token paths, and write-only secrets the provider never returns.

func (ModuleVar) VarType added in v0.6.0

func (v ModuleVar) VarType() string

VarType returns the type to declare for v, defaulting to string. A recovered variable carries the type the source environment declared for it, which is not always a string: the validation auto-fix answers a Required empty collection with a set(string), and declaring that one as a string produces a module terraform refuses to even validate.

type Options

type Options struct {
	Provider             string // "jamfpro" (default) or "jamfplatform"
	Envs                 []EnvConfig
	SourceEnv            string // name of source-of-truth env (default: first in Envs)
	OutputDir            string
	SelectedResources    map[string]bool
	SkipReferences       bool
	SkipImportBlocks     bool
	SkipPackageDownloads bool
	ProviderVersion      string
	Quiet                bool
	Verbose              bool
	ResourcesFlag        string
	ExcludeFlag          string
	StatusFunc           func(string, int, int)
}

Options holds all parameters for multi-environment export.

type PerEnvResult

type PerEnvResult struct {
	EnvName   string
	Registry  *registry.Registry
	Resources []ResourceRef // flat list of discovered resources for matching
	OutputDir string        // temp working directory for this env

	// ProcessOptions is the provider-specific post-processing configuration
	// (TypeToFileMap, Rules, ExtractSpecs, provider schema, etc.) built during
	// discovery. The merge pipeline clones it and overrides SupportFilesPrefix
	// and SkipReferences per call.
	ProcessOptions *postprocess.ProcessOptions

	// TokenRefreshPeriod is the provider's token refresh buffer in seconds, or 0
	// if the provider has no such attribute. Written into the env-root provider
	// block when non-zero.
	TokenRefreshPeriod int
}

PerEnvResult holds the pipeline output for a single environment. It is produced by Provider.DiscoverAndGenerate and consumed by the merge pipeline.

type Provider added in v0.4.0

type Provider interface {
	// Name is the provider identifier ("jamfpro", "jamfplatform").
	Name() string

	// ProviderSource is the registry source used to read the resolved version
	// from .terraform.lock.hcl (e.g. "deploymenttheory/jamfpro").
	ProviderSource() string

	// DiscoverAndGenerate runs discovery + terraform plan/query for one
	// environment into a fresh temp directory and returns a populated
	// PerEnvResult (the caller owns cleanup of result.OutputDir).
	DiscoverAndGenerate(env EnvConfig, opts *Options) (*PerEnvResult, error)

	// TypeToFileMap maps TF resource type → output filename.
	TypeToFileMap() map[string]string

	// ModuleProvidersBlock returns the required_providers block written to
	// modules/jamf/providers.tf. versionLine is the formatted version constraint
	// (may be empty).
	ModuleProvidersBlock(versionLine string) string

	// EnvProviderHeader returns the terraform{} + provider{} blocks for an
	// environment root's main.tf — everything that precedes the module call.
	EnvProviderHeader(env EnvConfig, versionLine string, tokenRefreshPeriod int) string

	// EnvAuthVariables returns the connection variable declarations for an
	// environment root's variables.tf (URL/auth/credentials).
	EnvAuthVariables(env EnvConfig) string

	// UsesIdentityImports reports whether this provider's import blocks address
	// an object by resource identity (`identity = { id = ... }`) rather than by
	// the flat `id = ...`.
	//
	// It decides the form the environment roots write, so that they match the
	// single-env export rather than diverging from it. It matters most for the
	// settings singletons, whose import id is the fixed sentinel "singleton":
	// on the flat form a singleton the tenant has not configured reports a
	// framework-level "Missing Resource Identity After Read", which tells the
	// operator to file a provider bug for what is really just an absent
	// setting. The identity form leaves state null, which the provider's Read
	// recognises, and it reports plainly that there is nothing to import.
	UsesIdentityImports() bool
}

Provider abstracts the per-provider specifics the merge pipeline needs: running discovery + generation for one environment, the reference/extraction configuration for post-processing, and the provider-specific Terraform blocks for the module and environment roots.

type ResourceRef added in v0.4.0

type ResourceRef struct {
	TFType string
	Label  string
	Name   string
	JamfID string
}

ResourceRef is a flat (type, label, name, id) record for a single resource, used to match resources across environments by (type, label) and to write per-env import blocks. Each provider produces these from its own discovery.

type SupportFileClass

type SupportFileClass int

SupportFileClass indicates whether a support file is identical across all environments (shared) or differs (divergent).

const (
	// SupportFileShared means the file is identical across all environments
	// and belongs in the shared module directory.
	SupportFileShared SupportFileClass = iota

	// SupportFileDivergent means the file differs across environments and
	// each environment gets its own copy.
	SupportFileDivergent
)

Jump to

Keyboard shortcuts

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