runtime

package
v0.60.0 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: Apache-2.0 Imports: 50 Imported by: 369

README

pkg/runtime

This package contains a set of concrete structs and helper functions that provide a common controller implementation for an AWS service.

The top-level container struct in the package is ServiceController. A single instance of ServiceController is created (using NewServiceController()) from the cmd/controller/main.go file that contains the ACK controller entrypoint for a specific AWS service API.

ServiceController primarily serves as a way to glue the upstream sigs.k8s.io/controller-runtime (here on called ctrlrt for short since that alias we use in the ACK codebase to refer to that upstream repository) machinery together with ACK types that handle communication with the AWS service API.

The main ctrlrt types that ServiceController glues together are the ctrlrt.Manager and ctrlrt.Reconciler types. The ctrlrt.Manager type is used to bind a bunch of sigs.k8s.io/client-go and sigs.k8s.io/apimachinery infrastructure together into a common network server/listener structure. The ctrlrt.Reconciler type is an interface that provides a single Reconcile() method whose job is to reconcile the state of a single custom resource (CR) object.

The ServiceController.BindControllerManager() method accepts a ctrlrt.Manager object and is responsible for creating a reconciler for each kind of CR that the service controller will handle.

But how does the ServiceController know what kinds of CRs that it will handle?

There is a ServiceController.WithResourceManagerFactories() method that sets the ServiceController's collection of objects that implement the types.AWSResourceManagerFactory interface.

These resource manager factories produce objects that implement the types.AWSResourceManager interface, which is basic CRUD+L operations for a particular AWS resource against the backend AWS service API. The types.AWSResourceManagerFactory.For() method returns a types.AWSResourceManager object that has been created to handle a specific AWS service API resources for one AWS account. In this way, the single service controller can manage resources across multiple AWS accounts.

Resource manager factories are registered with a Registry object that is package-scoped to the individual service controller's services/{service}/pkg/resource package. See the example service's pkg/resource/registry.go file for how this package-scoped registry works. Individual resource manager factories are registered with this package-scoped Registry object using an init() call within a file named {resource}_manager_factory.go. For example, the Book resource in the example service's pkg/resource package has its resource manager factory registered in the init() function in the pkg/resource/book_resource_manager_factory.go file.

Documentation

Index

Constants

View Source
const (
	// NamespaceKubeNodeLease is the name of the Kubernetes namespace that
	// contains the kube-node-lease resources (used for node hearthbeats)
	NamespaceKubeNodeLease = "kube-node-lease"
	// NamespacePublic is the name of the Kubernetes namespace that contains
	// the public info (ConfigMaps)
	NamespaceKubePublic = "kube-public"
	// NamespaceSystem is the name of the Kubernetes namespace where we place
	// system components.
	NamespaceKubeSystem = "kube-system"
)
View Source
const (
	// LabelManagedBy is the standard Kubernetes label for indicating which tool manages a resource
	LabelManagedBy = "app.kubernetes.io/managed-by"
	// LabelKroVersion is the kro-specific label for the kro version
	LabelKroVersion = "kro.run/kro-version"
	// LabelKroOwned is the legacy label for kro ownership (backward compatibility)
	LabelKroOwned = "kro.run/owned"
)

Label keys used by the runtime

View Source
const (
	// AdoptPolicy is ...
	AdoptionPolicy_Adopt AdoptionPolicy = "adopt"
	// AdoptPolicy is ...
	AdoptionPolicy_AdoptOrCreate AdoptionPolicy = "adopt-or-create"

	// Operation types for patch operations
	OperationType_MetadataSpec = "metadata+spec"
	OperationType_Status       = "status"
)
View Source
const CrossNamespaceOptInRequiredReason = "CrossNamespaceOptInRequired"

CrossNamespaceOptInRequiredReason is the Reason carried by the ACK.Advisory condition that notifies users their cross-namespace usage will require explicit opt-in (via --enable-cross-namespace=true) in a future release.

The cross-namespace deprecation notice is surfaced as a Reason on the existing ACK.Advisory condition rather than as a dedicated condition type. Advisory conditions are advisory-only (no programmatic dependencies are expected on them), which keeps this temporary notice cheap to add and to stop setting once the rollout completes, without the API-stability concerns of introducing and later removing a dedicated condition type. The reason is stable so support tooling can grep for it across resources.

View Source
const (
	// MissingImageTagValue is the placeholder value when ACK controller
	// image tag(release semver) cannot be determined.
	MissingImageTagValue = "unknown"
)

Variables

View Source
var ACKResourceTagFormats = map[string]resolveTagFormat{
	acktags.ServiceAliasTagFormat: func(
		obj rtclient.Object,
		md acktypes.ServiceControllerMetadata,
	) string {
		return md.ServiceAlias
	},

	acktags.ControllerVersionTagFormat: func(
		obj rtclient.Object,
		md acktypes.ServiceControllerMetadata,
	) string {
		controllerImageTag := md.GitVersion

		if controllerImageTag == "" {
			controllerImageTag = MissingImageTagValue
		}
		return controllerImageTag
	},

	acktags.NamespaceTagFormat: func(
		obj rtclient.Object,
		md acktypes.ServiceControllerMetadata,
	) string {
		return obj.GetNamespace()
	},

	acktags.ResourceNameTagFormat: func(
		obj rtclient.Object,
		md acktypes.ServiceControllerMetadata,
	) string {
		return obj.GetName()
	},

	acktags.ResourceKindTagFormat: func(
		obj rtclient.Object,
		md acktypes.ServiceControllerMetadata,
	) string {
		gvk := obj.GetObjectKind().GroupVersionKind()
		return gvk.Kind
	},

	acktags.ManagedByTagFormat: func(
		obj rtclient.Object,
		md acktypes.ServiceControllerMetadata,
	) string {
		return getManagedBy(obj.GetLabels())
	},

	acktags.KROVersionTagFormat: func(
		obj rtclient.Object,
		md acktypes.ServiceControllerMetadata,
	) string {
		return getKROVersion(obj.GetLabels())
	},
}

ACKResourceTagFormats is map of ACK resource tag formats to it's resolveTagFormat function.

To add a new ACKResourceTag format, include it in this map, along with the resolveTagFormat function and expandTagValue() method will start expanding the new resource tag format.

Localise the global to make it easier to mock

Functions

func ConditionManagerFromContext added in v0.60.0

func ConditionManagerFromContext(ctx context.Context) acktypes.ConditionManager

ConditionManagerFromContext returns the ConditionManager previously stored with WithConditionManager, or nil if none is present.

func CrossNamespaceAdvisory added in v0.60.0

func CrossNamespaceAdvisory(
	subject acktypes.ConditionManager,
) *ackv1alpha1.Condition

CrossNamespaceAdvisory returns the cross-namespace deprecation ACK.Advisory condition (Reason: CrossNamespaceOptInRequired) carried by subject, or nil if none is present. subject may be nil.

This is used to reconcile the advisory from the resource stashed in the reconcile context onto the resource that is actually patched back to the Kubernetes API, in cases where deep copies inside Sync (e.g. adopt-or-create) detach the two objects.

func ExtractAdoptionFields added in v0.40.0

func ExtractAdoptionFields(res acktypes.AWSResource) (map[string]string, error)

func GetDefaultTags

func GetDefaultTags(
	config *ackconfig.Config,
	obj rtclient.Object,
	md acktypes.ServiceControllerMetadata,
) acktags.Tags

GetDefaultTags provides Default tags (key value pairs) for given resource

func HandleCrossNamespaceReference added in v0.60.0

func HandleCrossNamespaceReference(
	ctx context.Context,
	conditions []*ackv1alpha1.Condition,
	refKind CrossNamespaceRefKind,
	ownerNamespace string,
	targetNamespace string,
	refName string,
) []*ackv1alpha1.Condition

HandleCrossNamespaceReference emits a Phase 1 deprecation warning log and sets the cross-namespace deprecation ACK.Advisory condition on the supplied conditions slice. It is intended to be called from generated code after ValidateCrossNamespaceReference reports isCrossNamespace=true.

Returns the updated conditions slice. Callers must assign the result back to the resource's Status.Conditions field.

func IsAdopted

func IsAdopted(res acktypes.AWSResource) bool

IsAdopted returns true if the supplied AWSResource was created with a non-nil ARN annotation, which indicates that the Kubernetes user who created the CR for the resource expects the ACK service controller to "adopt" a pre-existing resource and bring it under ACK management.

func IsManagedBy added in v0.54.0

func IsManagedBy(res acktypes.AWSResource, manager string) bool

IsManagedBy returns true if the supplied AWSResource has a label indicating that it is managed by the specified manager. It checks for the standard Kubernetes label app.kubernetes.io/managed-by.

func IsReadOnly added in v0.39.0

func IsReadOnly(res acktypes.AWSResource) bool

IsReadOnly returns true if the supplied AWSResource has an annotation indicating that it is in read-only mode.

func IsSynced

func IsSynced(res acktypes.AWSResource) bool

IsSynced returns true if the supplied AWSResource's CR and associated backend AWS service API resource are in sync.

func KROVersion added in v0.54.0

func KROVersion(res acktypes.AWSResource) string

KROVersion returns the kro version from the resource labels. Returns empty string if the kro.run/kro-version label is not present.

func NeedAdoption added in v0.40.0

func NeedAdoption(res acktypes.AWSResource) bool

NeedAdoption returns true when the resource has adopt annotation but is not yet adopted

func NewFieldExportReconcilerForAWSResource added in v0.18.0

func NewFieldExportReconcilerForAWSResource(
	sc acktypes.ServiceController,
	log logr.Logger,
	cfg ackcfg.Config,
	metrics *ackmetrics.Metrics,
	cache ackrtcache.Caches,
	rd acktypes.AWSResourceDescriptor,
) acktypes.FieldExportReconciler

NewFieldExportReconcilerForAWSResource returns a new FieldExportReconciler object

func NewFieldExportReconcilerForFieldExport added in v0.18.0

func NewFieldExportReconcilerForFieldExport(
	sc acktypes.ServiceController,
	log logr.Logger,
	cfg ackcfg.Config,
	metrics *ackmetrics.Metrics,
	cache ackrtcache.Caches,
) acktypes.FieldExportReconciler

NewFieldExportReconcilerForFieldExport returns a new FieldExportReconciler object

func NewFieldExportReconcilerWithClient added in v0.18.0

func NewFieldExportReconcilerWithClient(
	sc acktypes.ServiceController,
	log logr.Logger,
	cfg ackcfg.Config,
	metrics *ackmetrics.Metrics,
	cache ackrtcache.Caches,
	kc client.Client,
	apiReader client.Reader,
) acktypes.FieldExportReconciler

NewFieldExportReconcilerWithClient returns a new FieldExportReconciler object with specified k8s client and Reader. Currently this function is used for testing purpose only because "FieldExportReconciler" struct is not available outside 'runtime' package for dependency injection.

func NewFieldExportResourceReconcilerWithClient added in v0.18.0

func NewFieldExportResourceReconcilerWithClient(
	sc acktypes.ServiceController,
	log logr.Logger,
	cfg ackcfg.Config,
	metrics *ackmetrics.Metrics,
	cache ackrtcache.Caches,
	kc client.Client,
	apiReader client.Reader,
	rd acktypes.AWSResourceDescriptor,
) acktypes.FieldExportReconciler

NewFieldExportResourceReconcilerWithClient returns a new FieldExportReconciler object with specified k8s client and Reader. Currently this function is used for testing purpose only because "FieldExportReconciler" struct is not available outside 'runtime' package for dependency injection.

func NewReconciler

NewReconciler returns a new reconciler object

func NewReconcilerWithClient added in v0.7.0

NewReconcilerWithClient returns a new reconciler object with Client(controller-runtime/pkg/client) already set.

func NewServiceController

func NewServiceController(
	svcAlias string,
	svcAPIGroup string,
	versionInfo acktypes.VersionInfo,
) acktypes.ServiceController

NewServiceController returns a new serviceController instance

func ResolveCrossNamespaceReference added in v0.60.0

func ResolveCrossNamespaceReference(
	ctx context.Context,
	enableCrossNamespace bool,
	conditions *[]*ackv1alpha1.Condition,
	refKind CrossNamespaceRefKind,
	ownerNamespace string,
	refNamespace *string,
	refName string,
) (string, error)

ResolveCrossNamespaceReference orchestrates the full Phase 1 cross-namespace reference handling flow in a single call. It calls ValidateCrossNamespaceReference and, when the reference targets a different namespace and the flag is enabled, calls HandleCrossNamespaceReference to emit the warning log and set the cross-namespace deprecation ACK.Advisory condition.

Parameters:

  • ctx: passed to the logger
  • enableCrossNamespace: the value of Config.EnableCrossNamespace
  • conditions: pointer to the resource's Status.Conditions slice; the slice is updated in place when a deprecation condition is set
  • refKind: label describing the reference kind (resource, secret, ...)
  • ownerNamespace: the namespace of the resource containing the reference
  • refNamespace: the user-supplied namespace (may be nil or empty)
  • refName: the user-supplied reference name; used for log fields and error message context

Returns the resolved namespace to pass to apiReader.Get and any terminal error from ValidateCrossNamespaceReference. Callers do not need to inspect an isCrossNamespace flag or manage the conditions slice themselves.

func ResolveCrossNamespaceReferenceString added in v0.60.0

func ResolveCrossNamespaceReferenceString(
	ctx context.Context,
	enableCrossNamespace bool,
	conditions *[]*ackv1alpha1.Condition,
	refKind CrossNamespaceRefKind,
	ownerNamespace string,
	refNamespace string,
	refName string,
) (string, error)

ResolveCrossNamespaceReferenceString is the string-namespace counterpart of ResolveCrossNamespaceReference, intended for callers that have a plain string namespace (e.g. SecretKeyReference.Namespace, FieldExportTarget.Namespace) rather than a *string.

func SetCrossNamespaceOptInRequired added in v0.60.0

func SetCrossNamespaceOptInRequired(
	conditions []*ackv1alpha1.Condition,
	message string,
) []*ackv1alpha1.Condition

SetCrossNamespaceOptInRequired sets or updates the cross-namespace deprecation notice in the supplied conditions slice. The notice is surfaced as an ACK.Advisory condition carrying the CrossNamespaceOptInRequiredReason reason. A lookup-or-create pattern keyed on (type, reason) avoids duplicate conditions on repeated reconciles while preserving any other ACK.Advisory conditions the resource may carry.

Returns the (possibly modified) conditions slice. Callers must assign the result back to the resource's Status.Conditions field.

func SetCrossNamespaceOptInRequiredOnSubject added in v0.60.0

func SetCrossNamespaceOptInRequiredOnSubject(
	subject acktypes.ConditionManager,
	message string,
)

SetCrossNamespaceOptInRequiredOnSubject sets or updates the cross-namespace deprecation ACK.Advisory condition on the supplied ConditionManager (typically the resource being reconciled). It is a convenience wrapper for callers that hold a ConditionManager rather than a raw conditions slice.

func ValidateCrossNamespaceReference added in v0.60.0

func ValidateCrossNamespaceReference(
	enableCrossNamespace bool,
	ownerNamespace string,
	refNamespace *string,
	refName string,
) (string, bool, error)

ValidateCrossNamespaceReference inspects a user-supplied reference namespace and decides which namespace the controller should use when resolving the reference.

Parameters:

  • enableCrossNamespace: the value of Config.EnableCrossNamespace
  • ownerNamespace: the namespace of the resource containing the reference (never empty)
  • refNamespace: the Namespace field on the AWSResourceReference (may be nil or empty)
  • refName: the Name field on the AWSResourceReference; used only for error message context

Return values:

  • resolvedNamespace: the namespace to pass to apiReader.Get
  • isCrossNamespace: true if the reference targets a different namespace (callers should emit a deprecation warning when flag=true)
  • err: nil on success; a ResourceReferenceCrossNamespaceNotAllowed error when cross-namespace refs are disabled and the reference targets a different namespace

Same-namespace behavior (nil, empty, or equal refNamespace) is unaffected by the flag.

func ValidateCrossNamespaceReferenceString added in v0.60.0

func ValidateCrossNamespaceReferenceString(
	enableCrossNamespace bool,
	ownerNamespace string,
	refNamespace string,
	refName string,
) (string, bool, error)

ValidateCrossNamespaceReferenceString is a convenience wrapper for callers that have a string namespace (e.g., SecretKeyReference.Namespace, FieldExportTarget.Namespace) rather than a *string.

func WithConditionManager added in v0.60.0

func WithConditionManager(
	ctx context.Context,
	cm acktypes.ConditionManager,
) context.Context

WithConditionManager returns a copy of ctx that carries the supplied ConditionManager (typically the resource being reconciled). It is used so that code paths which only receive a context can still set conditions on the resource.

Types

type AdoptionPolicy added in v0.45.0

type AdoptionPolicy string

AdoptionPolicy stores adoptionPolicy values we expect users to provide in the resources `adoption-policy` annotation

TODO(michaelhtm) Maybe we need a different place for this... next refactor maybe? 🤷‍♂️

func GetAdoptionPolicy added in v0.40.0

func GetAdoptionPolicy(res acktypes.AWSResource) (AdoptionPolicy, error)

GetAdoptionPolicy returns the Adoption Policy of the resource defined by the user in annotation. Possible values are: adopt-only | adopt-or-create adopt-only keeps requing until the resource is found adopt-or-create creates the resource if does not exist

type CrossNamespaceRefKind added in v0.60.0

type CrossNamespaceRefKind string

CrossNamespaceRefKind is a label used in cross-namespace warning logs and condition messages to describe which kind of reference triggered the deprecation warning.

const (
	// CrossNamespaceRefKindResource indicates an AWSResourceReference
	// targeting a different namespace.
	CrossNamespaceRefKindResource CrossNamespaceRefKind = "resource reference"
	// CrossNamespaceRefKindSecret indicates a SecretKeyReference targeting
	// a different namespace.
	CrossNamespaceRefKindSecret CrossNamespaceRefKind = "secret reference"
)

type Registry

type Registry struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns a thread-safe Registry object

func (*Registry) GetResourceManagerFactories

func (r *Registry) GetResourceManagerFactories() []types.AWSResourceManagerFactory

GetResourceManagerFactories returns AWSResourceManagerFactories that are registered with the RegistryA

func (*Registry) RegisterResourceManagerFactory

func (r *Registry) RegisterResourceManagerFactory(f types.AWSResourceManagerFactory)

RegisterResourceManagerFactory registers a resource manager factory with the package's registry

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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