pluginutils

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Dec 6, 2025 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const SessionIDKey = "bluelink.sessionId"

SessionIDKey is the plain text key used to store the session ID in a Go context or as a part of the blueprint framework's context variables.

Variables

View Source
var (
	// ContextSessionIDKey is the context key used to store the session ID
	// in a Go context.
	ContextSessionIDKey = core.ContextKey(SessionIDKey)
)

Functions

func AnyToMappingNode

func AnyToMappingNode(data any) (*core.MappingNode, error)

AnyToMappingNode converts any JSON-like data to a MappingNode.

func CreateStringEqualsFilter

func CreateStringEqualsFilter(field string, value string) *provider.ResolvedDataSourceFilters

CreateStringEqualsFilter creates a resolved data source filters object that contains a single equality filter for the given field and string value. This is useful for things like creating filters that match a specific resource ID to be compatible with helpers like the `AdditionalValueExtractor` used for extracting values for a data source or when getting the external state of a resource.

func ExtractFirstMatchFromFilters

func ExtractFirstMatchFromFilters(
	filters *provider.ResolvedDataSourceFilters,
	fields []string,
) *core.MappingNode

ExtractFirstMatchFromFilters extracts the first field match from the filters that matches one of the provided identifiers. It returns the first matching filter's search value as a MappingNode, or nil if no match is found. An example use case for this could be when you have an "ARN" and a unique "Name" field for an AWS resource, and you want to extract either value from the filters to use in a service call.

func ExtractMatchFromFilters

func ExtractMatchFromFilters(
	filters *provider.ResolvedDataSourceFilters,
	field string,
) *core.MappingNode

ExtractMatchFromFilters extracts a specific field match from the filters that matches the provided field name with an equality operator. It returns the matching filter's search value as a MappingNode, or nil if no match is found.

func FieldChangesToNewValueMap

func FieldChangesToNewValueMap(
	changes ...[]provider.FieldChange,
) map[string]*core.MappingNode

FieldChangesToNewValueMap converts a slice of FieldChange structs to a map where the keys are the field paths and the values are pointers to the corresponding new value for the field. This is useful for creating lookups for potentially large sets of field changes, allowing for quick access to new values by field paths.

Multiple slices of field changes can be provided, as a convenience when merging new and modified field changes into a single map.

func FieldChangesToPrevValueMap

func FieldChangesToPrevValueMap(
	changes ...[]provider.FieldChange,
) map[string]*core.MappingNode

FieldChangesToPrevValueMap converts a slice of FieldChange structs to a map where the keys are the field paths and the values are pointers to the corresponding previous value for the field. This is useful for creating lookups for potentially large sets of field changes, allowing for quick access to previous values by field paths.

Multiple slices of field changes can be provided, as a convenience when merging new and modified field changes into a single map.

func GetBoolAnnotation

func GetBoolAnnotation(
	resourceInfo *provider.ResourceInfo,
	query *AnnotationQuery[bool],
) (bool, bool)

GetBoolAnnotation retrieves a boolean annotation from the resource info. It returns the value of the annotation if it exists, otherwise it returns the default value. The second return value indicates whether an annotation was found for the provided query, it will be false if the default value was returned.

func GetCurrentResourceStateSpecData

func GetCurrentResourceStateSpecData(changes *provider.Changes) *core.MappingNode

GetCurrentResourceStateSpecData returns the spec data for the current resource state from the changes object.

func GetCurrentStateSpecDataFromResourceInfo

func GetCurrentStateSpecDataFromResourceInfo(
	resourceInfo *provider.ResourceInfo,
) *core.MappingNode

GetCurrentStateSpecDataFromResourceInfo extracts the current resource state's spec data from the resource info. If the resource info or current resource state is nil, it returns a MappingNode with an empty set of fields.

func GetDataSourceFilterOperator

func GetDataSourceFilterOperator(
	dataSourceFilter *provider.ResolvedDataSourceFilter,
) schema.DataSourceFilterOperator

GetDataSourceFilterOperator is a utility function that safely retrieves a data source filter operator from a resolved data source filter without producing a nil pointer dereference error. An empty string is returned if the operator is not set.

func GetDataSourceFilterSearchValue

func GetDataSourceFilterSearchValue(
	dataSourceFilter *provider.ResolvedDataSourceFilter,
	index int,
) *core.MappingNode

GetDataSourceFilterSearchValue is a utility function that safely retrieves a data source filter search value from a resolved data source filter without producing a nil pointer dereference error. It returns nil if the search value is not set or if the index is out of bounds.

func GetDataSourceFilterSearchValues

func GetDataSourceFilterSearchValues(
	dataSourceFilter *provider.ResolvedDataSourceFilter,
) []*core.MappingNode

GetDataSourceFilterSearchValues is a utility function that safely retrieves data source filter search values from a resolved data source filter without producing a nil pointer dereference error. It returns an empty slice if the search values are not set.

func GetFloatAnnotation

func GetFloatAnnotation(
	resourceInfo *provider.ResourceInfo,
	query *AnnotationQuery[float64],
) (float64, bool)

GetFloatAnnotation retrieves a float annotation from the resource info. It returns the value of the annotation if it exists, otherwise it returns the default value.

func GetInstanceID

func GetInstanceID(resourceInfo *provider.ResourceInfo) string

GetInstanceID retrieves the instance ID from the resource info. If the resource info is nil, it returns "unknown".

func GetIntAnnotation

func GetIntAnnotation(
	resourceInfo *provider.ResourceInfo,
	query *AnnotationQuery[int],
) (int, bool)

GetIntAnnotation retrieves an integer annotation from the resource info. It returns the value of the annotation if it exists, otherwise it returns the default value.

func GetModifiedField

func GetModifiedField(
	changes *provider.Changes,
	fieldPath string,
) *provider.FieldChange

GetModifiedField retrieves the modified field from the changes object based on the specified field path. If no such field exists, it returns nil.

func GetNewField

func GetNewField(
	changes *provider.Changes,
	fieldPath string,
) *provider.FieldChange

GetNewField retrieves the new field from the changes object based on the specified field path. If no such field exists, it returns nil.

func GetResolvedResourceSpecData

func GetResolvedResourceSpecData(changes *provider.Changes) *core.MappingNode

GetResolvedResourceSpecData returns the resolved spec data for the resource from changes.

func GetResourceName

func GetResourceName(resourceInfo *provider.ResourceInfo) string

GetResourceName safely retrieves the resource name from the provided resource info struct. If the resource info is nil, it returns "unknown".

func GetStringAnnotation

func GetStringAnnotation(
	resourceInfo *provider.ResourceInfo,
	query *AnnotationQuery[string],
) (string, bool)

GetStringAnnotation retrieves a string annotation from the resource info. It returns the value of the annotation if it exists, otherwise it returns the default value.

func GetValueByPath

func GetValueByPath(
	fieldPath string,
	specData *core.MappingNode,
) (*core.MappingNode, bool)

GetValueByPath is a helper function to extract a value from a mapping node that is a thin wrapper around the blueprint framework's `core.GetPathValue` function. Unlike core.GetPathValue, this function will not return an error, instead it will return nil and false if the value is not found or the provided path is not valid.

func HasChildModifiedField

func HasChildModifiedField(
	changes *provider.Changes,
	fieldPathPrefix string,
) bool

HasChildModifiedField checks if there is a modified field that is a child of the specified field path.

func HasModifiedField

func HasModifiedField(
	changes *provider.Changes,
	fieldPath string,
) bool

HasModifiedField checks if the specified field path has been modified in the changes object.

func HasNewField

func HasNewField(
	changes *provider.Changes,
	fieldPath string,
) bool

HasNewField checks if the specified field path has been added as a new field in the changes object.

func IsResourceNew

func IsResourceNew(changes *provider.Changes) bool

IsResourceNew checks if the provided changes indicate that a new resource is being created or an existing resource is being recreated. This is useful for tasks like determining the changes that should be reported for a link implementation where changes to the link data are determined by the changes to the resources that are linked.

func MergeFieldChanges

func MergeFieldChanges(
	changes ...[]provider.FieldChange,
) []provider.FieldChange

MergeFieldChanges combines multiple slices of FieldChange into a single slice. This is useful for combining field changes for modified and new fields.

func RunAdditionalValueExtractors

func RunAdditionalValueExtractors[Service any](
	ctx context.Context,
	filters *provider.ResolvedDataSourceFilters,
	targetMap map[string]*core.MappingNode,
	extractors []AdditionalValueExtractor[Service],
	service Service,
) error

RunAdditionalValueExtractors runs a list of additional value extractors and returns true if any of the extractors were applied.

func RunOptionalValueExtractors

func RunOptionalValueExtractors[Input any](
	input Input,
	targetMap map[string]*core.MappingNode,
	extractors []OptionalValueExtractor[Input],
) error

RunOptionalValueExtractors runs a list of optional value extractors and returns true if any of the extractors were applied.

func ShallowCopy

func ShallowCopy(
	fields map[string]*core.MappingNode,
	ignoreKeys ...string,
) map[string]*core.MappingNode

ShallowCopy creates a shallow copy of a map of MappingNodes, excluding the keys in the ignoreKeys slice.

func StripNonAlphaNumericChars

func StripNonAlphaNumericChars(s string) string

StripNonAlphaNumericChars strips all non-alphanumeric characters from a string.

func WaitForShutdown

func WaitForShutdown(closer func())

WaitForShutdown is a helper function that waits for a shutdown signal and then calls the provided closer function.

Types

type AdditionalValueExtractor

type AdditionalValueExtractor[Service any] struct {
	// Name is the name of the extractor, used for logging and debugging.
	Name string
	// Extract is a function that performs the service call
	// and extracts values from the service response.
	Extract func(
		ctx context.Context,
		filters *provider.ResolvedDataSourceFilters,
		targetData map[string]*core.MappingNode,
		service Service,
	) error
}

AdditionalValueExtractor is a helper struct that allows defining additional value extractors for a data source or the `GetExternalState` method of a resource. This is usually used to make additional service API calls to retrieve additional values that are needed to populate the data source or resource spec.

type AnnotationQuery

type AnnotationQuery[AnnotationType any] struct {
	// Key is the primary key to retrieve the annotation.
	// This is usually a more targeted key that will include a targeted resource
	// name in the annotation key.
	// For example, "aws.lambda.function.myFunction.populateEnvVars" would be
	// a targeted key for the link annotation definition
	// "aws.lambda.function.<resourceName>.populateEnvVars".
	// For simple cases, this will be a static documented key when targeting
	// specific resources in a blueprint is not supported.
	Key string
	// FallbackKey is the fallback key to retrieve the annotation.
	// This is usually a more generic key that will include the resource type
	// in the annotation key.
	// For example, "aws.lambda.function.populateEnvVars" would be a general key
	// that applies to all outgoing or incoming links that involve the current resource type.
	FallbackKey string
	// The default value to return if the annotation could not be found.
	Default AnnotationType
}

AnnotationQuery is a simple structure that holds query parameters for retrieving annotations from resource information passed into the methods of a link in a provider plugin.

type ContextFunc

type ContextFunc[Arg any] func(context.Context, Arg) error

ContextFunc is a function that takes a context and an argument and returns an error.

func Retryable

func Retryable[Arg any](
	function ContextFunc[Arg],
	isErrorRetryable func(error) bool,
) ContextFunc[Arg]

Retryable wraps a function that only returns an error and makes it retryable in the plugin system if the error meets the provided retryable criteria. This is to be used inside the body of a plugin definition handler and wrapped around all the functionality that needs to be retried.

func Timeout

func Timeout[Arg any](function ContextFunc[Arg], timeout time.Duration) ContextFunc[Arg]

Timeout wraps a function that only returns an error and applies a timeout to it. Timeouts can be due to transient or permanent issues, to combine timeout and retry behaviour, wrap the timeout function with Retryable.

type ContextFuncReturnValue

type ContextFuncReturnValue[Arg any, Value any] func(context.Context, Arg) (Value, error)

ContextFuncReturnValue is a function that takes a context, an argument and returns a value and an error.

func RetryableReturnValue

func RetryableReturnValue[Arg any, Value any](
	function ContextFuncReturnValue[Arg, Value],
	isErrorRetryable func(error) bool,
) ContextFuncReturnValue[Arg, Value]

RetryableReturnValue wraps a function that returns a value and an error and makes it retryable in the plugin system. This is to be used inside the body of a plugin definition handler and wrapped around all the functionality that needs to be retried.

func TimeoutReturnValue

func TimeoutReturnValue[Arg any, Value any](
	function ContextFuncReturnValue[Arg, Value],
	timeout time.Duration,
) ContextFuncReturnValue[Arg, Value]

TimeoutReturnValue wraps a function that returns a value and an error and applies a timeout to it. Timeouts can be due to transient or permanent issues, to retry a timeout error, wrap the timeout function with RetryableReturnValue.

type ContextKey

type ContextKey string

ContextKey provides a unique key type for Bluelink context variables.

func (ContextKey) String

func (c ContextKey) String() string

type HostInfoContainer

type HostInfoContainer interface {
	// GetID returns the ID of the host system that the plugin is running for.
	GetID() string
	// SetID sets the ID of the host system that the plugin is running for.
	SetID(id string)
}

HostInfoContainer is an interface that represents a container for host information.

func NewHostInfoContainer

func NewHostInfoContainer() HostInfoContainer

NewHostInfoContainer creates a new container for host information that is used by a plugin built with the plugin SDK to carry out tasks like check that the host making requests is the same as the host the plugin was registered with on initialisation.

type LinkServiceDeps

type LinkServiceDeps[
	ResourceAServiceConfig any,
	ResourceAService any,
	ResourceBServiceConfig any,
	ResourceBService any,
] struct {
	// ResourceAService is a service factory and
	// config store for the first resource (resource A).
	ResourceAService ServiceWithConfigStore[ResourceAServiceConfig, ResourceAService]
	// ResourceBService is a service factory and
	// config store for the second resource (resource B).
	ResourceBService ServiceWithConfigStore[ResourceBServiceConfig, ResourceBService]
}

LinkServiceDeps is a struct that holds dependencies that can be used to create a link between two resources that supports cross-provider links.

func NewSingleLinkServiceDeps

func NewSingleLinkServiceDeps[
	ResourceServiceConfig any,
	ResourceService any,
](
	singleServiceFactory ServiceFactory[ResourceServiceConfig, ResourceService],
	singleServiceConfigStore ServiceConfigStore[ResourceServiceConfig],
) LinkServiceDeps[ResourceServiceConfig, ResourceService, ResourceServiceConfig, ResourceService]

NewLinkServiceDeps creates a new instance of a LinkServiceDeps struct using a single service factory and config store for both resources in the link.

type OptionalValueExtractor

type OptionalValueExtractor[Input any] struct {
	// Name is the name of the extractor, used for logging and debugging.
	Name string
	// Condition is a function that returns true if the extractor should be applied.
	// If the condition returns false, the extractor will be skipped.
	Condition func(input Input) bool
	// Fields is a list of fields that the extractor will
	// populate in the target data map.
	Fields []string
	// Values is a function that returns the values to be extracted.
	// It should return a slice of MappingNode pointers, or an error if the extraction fails.
	// The values will be added to the target data map under the keys specified in the Fields slice
	// in the order they are defined.
	Values func(input Input) ([]*core.MappingNode, error)
}

OptionalValueExtractor is a helper struct that allows defining optional value extractors for a data source or the `GetExternalState` method of a resource. This is usually used to conditionally extract values that are not required based on some condition.

type SaveOperation

type SaveOperation[Service any] interface {
	// Name of the save operation, used for logging and error messages.
	Name() string
	// Prepare an operation, primarily used to transform resource spec
	// data into a format that can be used to make service calls
	// to the upstream provider.
	Prepare(
		saveOpCtx SaveOperationContext,
		specData *core.MappingNode,
		changes *provider.Changes,
	) (bool, SaveOperationContext, error)
	// Execute an operation, used to make service calls to the upstream provider.
	Execute(
		ctx context.Context,
		saveOpCtx SaveOperationContext,
		service Service,
	) (SaveOperationContext, error)
}

SaveOperation is a generic interface for save operations that are combined as a part of a resource update or creation that spans multiple provider service calls. For example, an AWS lambda function update will often involve multiple calls including updating the function configuration and updating the function code.

type SaveOperationContext

type SaveOperationContext struct {
	// ProviderUpstreamID is the ID of the resource in the upstream provider.
	// For example, if the resource is an AWS resource, this will be the ARN.
	ProviderUpstreamID string
	// Data collected from previous save operations.
	// It is used to pass data to subsequent save operations.
	Data map[string]any
}

SaveOperationContext is context collected when applying multiple save operations. It is mostly useful when creating a resource involves multiple actions where a previous action returns values that are required by subsequent actions.

func RunSaveOperations

func RunSaveOperations[Service any](
	ctx context.Context,
	saveOpCtx SaveOperationContext,
	operations []SaveOperation[Service],
	input *provider.ResourceDeployInput,
	service Service,
) (bool, SaveOperationContext, error)

RunSaveOperations runs a list of save operations in sequence. It returns true if any of the save operations resulted in an update or resource creation. It returns an error if any of the save operations fail. An initial context can be provided (can be empty), this will be passed through all the save operations where each operation will make a copy of the context and will return a new context with the updated data.

type ServiceConfigStore

type ServiceConfigStore[ServiceConfig any] interface {
	// FromProviderContext derives service-specific configuration
	// from the provider context for the current request to the provider plugin.
	FromProviderContext(
		ctx context.Context,
		providerContext provider.Context,

		meta map[string]*core.MappingNode,
	) (ServiceConfig, error)
}

ServiceConfigStore is an interface that defines a method to retrieve service-specific configuration for a service factory to create an instance of the service. The `ServiceConfig` type parameter should be the config required by client libraries for the service provider, such as `*aws.Config` for AWS services.

It is a good practise to use a store that caches service configuration for a session to reuse the same configuration between calls to the same plugin that are a part of the same deployment process/session. Provider-specific configuration will almost always be derived from the provider context, so implementing config stores with the `FromProviderContext` method is a good approach that will also allow you to use the resource test tools that are provided in the `plugintestutils` package.

type ServiceFactory

type ServiceFactory[ServiceConfig any, Service any] func(
	serviceConfig ServiceConfig,
	providerContext provider.Context,
) Service

ServiceFactory is a function type that creates an instance of a service that will usually be a client for the provider service API.

type ServiceWithConfigStore

type ServiceWithConfigStore[ServiceConfig any, Service any] struct {
	ServiceFactory ServiceFactory[ServiceConfig, Service]
	ConfigStore    ServiceConfigStore[ServiceConfig]
}

ServiceWithConfigStore is a struct that holds a service factory and a config store for a service. This is useful for passing multiple services to cross-provider link implementations.

type ValueSetter

type ValueSetter[Target any] struct {
	// contains filtered or unexported fields
}

ValueSetter is a helper struct that can be used to set a value in a from a resource spec or other framework-specific use of a mapping node to a target API-specific struct used to update or create a resource or link in the upstream provider.

func NewValueSetter

func NewValueSetter[Target any](
	path string,
	setValueFunc func(
		value *core.MappingNode,
		target Target,
	),
	opts ...ValueSetterOption[Target],
) *ValueSetter[Target]

NewValueSetter creates a new value setter for the given path and setter function that will set the value in the target struct if the path exists in a given value mapping node, optionally checking if the value has changed based on a pre-computed list of modified fields.

func (*ValueSetter[Target]) DidSet

func (u *ValueSetter[Target]) DidSet() bool

DidSet checks if the value was set by the setter, this is useful to determine if an update should take place based on whether or not any values have been set on the target.

func (*ValueSetter[Target]) Set

func (s *ValueSetter[Target]) Set(
	parent *core.MappingNode,
	target Target,
)

Sets the value in the target struct if the value exists in the given mapping node at the specified path. If checkIfChanged is true, it will only set the value if the path is in the configured modified fields list.

type ValueSetterOption

type ValueSetterOption[Target any] func(*ValueSetter[Target])

ValueSetterOption is a functional option type for configuring a ValueSetter.

func WithValueSetterCheckIfChanged

func WithValueSetterCheckIfChanged[Target any](
	checkIfChanged bool,
) ValueSetterOption[Target]

WithValueSetterCheckIfChanged is an option that can be used to configure the ValueSetter to check if the value has changed before setting it. This is useful for avoiding unnecessary updates to the target when the current operation is for an update but is only used when the setter is configured with a modified fields list for the current context.

func WithValueSetterModifiedFields

func WithValueSetterModifiedFields[Target any](
	modifiedFields []provider.FieldChange,
	pathRoot string,
) ValueSetterOption[Target]

WithValueSetterModifiedFields is an option that can be used to configure the ValueSetter with a list of modified fields. This is useful for the setter to know which fields have been modified in the current context, so it can check if the value has changed before setting it, if the setter is configured with WithValueSetterCheckIfChanged.

The pathRoot is used to determine the root object for to use in the modified field paths. For example, if the pathRoot is "spec", any modified fields that have the prefix "spec(\.|\[)" will be replaced with "$(\.|\[)" to compare with the value path. pathRoot can be set to an empty string if the modified fields are already relative to the root of the path, a "$." prefix is added to the modified field paths when comparing with the value path. pathRoot must be an exact match with the prefix of the modified field paths.

Jump to

Keyboard shortcuts

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