### TLS Configuration Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt Example configuration for TLS settings in the CLI. ```Go type TLSConfig struct { CertFile string KeyFile string CAFile string } ``` -------------------------------- ### Example Usage of Function Tag Manager Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt This is a general usage example for the function tag manager, demonstrating its integration within a larger system. It serves as a starting point for understanding how to apply the tag management functionalities. ```Go package main import ( "context" "fmt" "github.com/crossplane/crossplane-runtime/apis/common/v1" "github.com/crossplane/crossplane-runtime/pkg/logging" "github.com/crossplane/function-sdk-go/resource" "github.com/crossplane/function-sdk-go/run" pkg "github.com/crossplane-contrib/function-tag-manager/apis/tag/v1alpha1" ) func main() { ctx := context.Background() log := logging.NewLogger(logging.UseDevMode(true)) // Example: Run a function with a specific configuration. // This demonstrates the entry point for executing the tag manager function. run.Run(ctx, log, &pkg.TagManager{}, run.WithMode(run.ModeAll), run.Listen(":8080")) } // TagManager implements the function.Function interface. // It handles the core logic for managing tags on resources. type TagManager struct{} // Run executes the function's logic against the desired state. // It processes resources and applies tag management operations based on configuration. func (m *TagManager) Run(ctx context.Context, log logging.Logger, ctrl run.Controller) error { log.Info("Running TagManager function") // Fetch the desired state from the control plane. desired, err := ctrl.GetDesiredState(ctx) if err != nil { return fmt.Errorf("failed to get desired state: %w", err) } // Process each resource in the desired state. for _, obj := range desired.Resources { // Check if the object is a managed resource. if !resource.IsManaged(obj) { continue } log.Debug("Processing resource", "name", obj.GetName()) // Apply tag management logic based on the function's configuration. // This is where specific tag operations (add, ignore, remove) are performed. // For example, if a configuration specifies adding tags, this section would handle it. // The actual implementation would involve inspecting the function's configuration // and the resource's current state to determine the necessary actions. // Example placeholder for tag application logic: // if err := m.applyTags(ctx, log, obj, desired.Function); err != nil { // log.Error(err, "failed to apply tags") // // Depending on error handling strategy, you might return the error or continue. // } } // Update the desired state with any modifications made by the function. if err := ctrl.UpdateDesiredState(ctx, desired); err != nil { return fmt.Errorf("failed to update desired state: %w", err) } return nil } // Placeholder for applying tags to a resource. // This function would contain the detailed logic for adding, ignoring, or removing tags. func (m *TagManager) applyTags(ctx context.Context, log logging.Logger, obj resource.Object, functionConfig *resource.Composite) error { // Implementation details for tag application would go here. // This would involve parsing the functionConfig for tag rules and applying them to obj. log.Info("Applying tags to resource", "resource", obj.GetName()) return nil } ``` -------------------------------- ### Field Path Reference Examples Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/README.md Examples demonstrating dot-notation for accessing nested fields in configurations. Use these to target specific fields for tag management. ```text spec.parameters.tags # Access tags field in parameters status.atProvider.commonTags # Access cloud provider response metadata.labels.environment # Access Kubernetes labels ``` -------------------------------- ### AddTags Configuration Examples Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/configuration.md Examples demonstrating how to configure `addTags` using static values, composite field paths, and environment field paths with different merge policies. ```yaml addTags: - type: FromValue policy: Replace tags: Environment: production CostCenter: "12345" - type: FromCompositeFieldPath fromFieldPath: spec.parameters.customTags policy: Retain - type: FromEnvironmentFieldPath fromFieldPath: commonTags policy: Replace ``` -------------------------------- ### Example Usage of NewResourceFilter Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md Shows how to initialize a ResourceFilter using NewResourceFilter and then use it to check individual resources for tag management compatibility. ```go // Initialize filter once for the entire function execution filter := filters.NewResourceFilter() // Use the filter to check each resource for name, desired := range desiredComposed { if SupportedManagedResource(desired, filter) { // Apply tag management to this resource } } ``` -------------------------------- ### Install Crossplane CLI Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Download and install the Crossplane CLI using a provided script. This is a prerequisite for building Crossplane packages. ```shell curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | XP_CHANNEL=stable sh ``` -------------------------------- ### Error Handling Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt Illustrates basic error handling within the CLI. ```Go if err := cli.Run(ctx); err != nil { log.Fatalf("CLI execution failed: %v", err) } ``` -------------------------------- ### Example Usage of ExamineFieldFromCRDVersions Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/generator.md This example demonstrates how to use the ExamineFieldFromCRDVersions function. It calls the function with a filesystem and a directory path, then checks for errors. The resulting filters indicate which resources support the 'tags' field. ```go filters, err := ExamineFieldFromCRDVersions(filesystem, "package/crds") if err != nil { log.Fatal(err) } // filters contains entries like: // {GroupKind: "ec2.aws.upbound.io/Instance", Enabled: true} // {GroupKind: "iam.aws.upbound.io/User", Enabled: false} ``` -------------------------------- ### Example ResourceFilter Structure Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md Illustrates the structure of a ResourceFilter map, showing example Kubernetes GroupKind identifiers and their tag support status. ```go filter := ResourceFilter{ "ec2.aws.upbound.io/Instance": true, "ec2.aws.upbound.io/SecurityGroup": true, "iam.aws.upbound.io/User": false, "iam.aws.upbound.io/Role": true, "storage.azure.upbound.io/StorageAccount": true, "network.azure.upbound.io/PublicIP": false, } ``` -------------------------------- ### Example Usage of Tags Map Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/types.md Illustrates how to define and initialize a Tags map with key-value pairs for environment, cost center, owner, and application. ```go tags := Tags{ "Environment": "production", "CostCenter": "12345", "Owner": "platform-team", "Application": "my-app", } ``` -------------------------------- ### gRPC Request Structure Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt Example structure for a gRPC request message. ```proto message RunRequest { Composed run = 1; } ``` -------------------------------- ### Environment-Based Tags Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/integration-examples.md This example demonstrates how to use Composition Environment to provide common tags for all resources managed by a composition. It also shows how to add specific tags and allow overrides from the resource request. ```yaml apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: environment-aware-tagging spec: compositeTypeRef: apiVersion: data.example.com/v1 kind: Database mode: Pipeline # Environment provides common tags for all databases environment: data: commonTags: DataClassification: confidential BackupRequired: "true" MonitoringEnabled: "true" pipeline: - step: provision-database functionRef: name: db-provisioner - step: apply-environment-tags functionRef: name: crossplane-contrib-function-tag-manager input: apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: # Add environment-provided tags - type: FromEnvironmentFieldPath fromFieldPath: commonTags policy: Replace # Add specific tags for this composition - type: FromValue policy: Replace tags: ManagedBy: Crossplane CompositionName: environment-aware-tagging # Allow override from resource request - type: FromCompositeFieldPath fromFieldPath: spec.parameters.additionalTags policy: Retain ``` -------------------------------- ### Install Crossplane Azure Provider Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/examples/configuration-azure-network/README.md Apply the provider configuration to install the Azure provider for Crossplane. ```shell kubectl apply -f provider.yaml ``` -------------------------------- ### Profile Function with Go Tools Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Starts the function and then uses Go's pprof tool to profile its performance. Requires importing `_ "net/http/pprof"` and running the pprof server. ```bash go run . --insecure & go tool pprof http://localhost:6060/debug/pprof/profile ``` -------------------------------- ### gRPC Response Structure Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt Example structure for a gRPC response message. ```proto message RunResponse { repeated Composition compositions = 1; repeated Event events = 2; } ``` -------------------------------- ### Generator Clone Method Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/generator.md Example demonstrating how to use the Generator's Clone method to perform a sparse checkout of a Git repository. Ensure the Cloner's Paths and Reference are correctly set. ```go gen := Generator{ RepoURL: "https://github.com/crossplane-contrib/provider-upjet-aws.git", Cloner: Cloner{ Paths: []string{"package/crds"}, Reference: "refs/remotes/origin/main", }, } wt, err := gen.Clone() if err != nil { log.Fatal(err) } // wt.Filesystem can now be used to access the cloned repository ``` -------------------------------- ### Code Example: Label-based Ignore (Backward Compatible) Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md Go code demonstrating how to create a DesiredComposed resource with a label to ignore tag management and call the IgnoreResource function. ```go // Label-based ignore (backward compatible) resource = &resource.DesiredComposed{ Resource: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "labels": map[string]interface{}{ "tag-manager.fn.crossplane.io/ignore-resource": "true", }, }, }, }, } shouldIgnore = IgnoreResource(resource) // shouldIgnore = true ``` -------------------------------- ### ManagedTags Input Configuration Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/function.md Example YAML configuration for the ManagedTags input, specifying tags to add, ignore, and remove. ```yaml apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: - type: FromValue policy: Replace tags: Environment: production Owner: platform-team - type: FromCompositeFieldPath fromFieldPath: spec.parameters.additionalTags policy: Retain ignoreTags: - type: FromValue policy: Replace keys: - external-tag-1 - external-tag-2 removeTags: - type: FromValue keys: - temporary-tag ``` -------------------------------- ### Code Example: Annotation-based Ignore (Preferred) Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md Go code demonstrating how to create a DesiredComposed resource with an annotation to ignore tag management and call the IgnoreResource function. ```go // Annotation-based ignore (preferred) resource := &resource.DesiredComposed{ Resource: &unstructured.Unstructured{ Object: map[string]interface{}{ "metadata": map[string]interface{}{ "annotations": map[string]interface{}{ "tag-manager.fn.crossplane.io/ignore-resource": "true", }, }, }, }, } shouldIgnore := IgnoreResource(resource) // shouldIgnore = true ``` -------------------------------- ### IgnoreTags Configuration Examples Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/configuration.md Examples showing `ignoreTags` configuration for preserving external tag keys using static values or field paths, with specified merge policies. ```yaml ignoreTags: - type: FromValue policy: Replace keys: - aws:cloudformation:stack-name - aws:cloudformation:stack-id - elasticbeanstalk:environment-name - type: FromCompositeFieldPath fromFieldPath: spec.parameters.externalTagKeys policy: Retain ``` -------------------------------- ### Field Path Examples Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/configuration.md Examples of field paths used to extract tag data from resource specifications and status. ```plaintext spec.parameters.tags status.atProvider.commonTags metadata.labels.environment ``` -------------------------------- ### gRPC Function Error Context Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Provides an example of how to wrap errors with context, including what failed, why it failed, and the type that caused the failure. This is crucial for effective debugging. ```go if err != nil { response.Fatal(rsp, errors.Wrapf(err, "cannot get observed composed resources from %T", req)) return rsp, nil } ``` -------------------------------- ### Tag Cleanup and Migration Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/integration-examples.md This example shows how to remove deprecated tags while retaining other tags using the tag manager function. It demonstrates removing tags by their keys and by a field path from the composite resource specification. ```yaml apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: tag-cleanup spec: compositeTypeRef: apiVersion: network.example.com/v1 kind: VirtualNetwork mode: Pipeline pipeline: - step: update-network functionRef: name: network-updater - step: cleanup-tags functionRef: name: crossplane-contrib-function-tag-manager input: apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: - type: FromValue policy: Replace tags: ManagedBy: Crossplane VersionControl: enabled # Remove tags that were used in previous tagging scheme removeTags: - type: FromValue keys: - OldOwner - OldProject - LegacyManagement - DeprecatedTag # Also remove tags specified in the resource - type: FromCompositeFieldPath fromFieldPath: spec.parameters.deprecatedTags ``` -------------------------------- ### RemoveTags Configuration Examples Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/configuration.md Examples for configuring `removeTags` to delete specific tag keys from composed resources, using static values or field paths. ```yaml removeTags: - type: FromValue keys: - temporary-tag - debug-flag - type: FromCompositeFieldPath fromFieldPath: spec.parameters.deprecatedTags ``` -------------------------------- ### CI/CD Driven Tagging for Deployment Units Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/integration-examples.md This example demonstrates how to apply tags to deployment units based on information injected by a CI/CD pipeline, such as Git commit and branch. Use this to track deployment provenance and status. ```yaml apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: cicd-aware-tagging spec: compositeTypeRef: apiVersion: cicd.example.com/v1 kind: DeploymentUnit mode: Pipeline pipeline: - step: deploy functionRef: name: deployer - step: tag-for-cicd functionRef: name: crossplane-contrib-function-tag-manager input: apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: - type: FromValue policy: Replace tags: # Injected by CI/CD pipeline GitCommit: "abc123def456" GitBranch: "main" PipelineRun: "12345" BuiltBy: "github-actions" SourceRepo: "github.com/acme/infrastructure" - type: FromCompositeFieldPath fromFieldPath: spec.parameters.cicdMetadata policy: Replace ``` -------------------------------- ### IgnoreTag Configuration Example Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/types.md Illustrates how to configure ignoreTags using static keys or by extracting keys from a composite field path. ```yaml ignoreTags: - type: FromValue policy: Replace keys: - external-tag-1 - aws:cloudformation:stack-name - type: FromCompositeFieldPath fromFieldPath: spec.parameters.ignoreTagKeys policy: Retain ``` -------------------------------- ### Install Required Functions Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/examples/configuration-azure-network/README.md Apply the necessary Crossplane functions to manage Azure resources. ```shell kubectl apply -f functions.yaml ``` -------------------------------- ### Example Usage of SupportedManagedResource Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md Demonstrates how to create a resource filter and use the SupportedManagedResource function to check if an EC2 Instance supports tags and if an unsupported resource is correctly filtered out. ```go // Creating a filter that includes selected AWS EC2 resources filter := filters.NewResourceFilter() // Check if an EC2 Instance supports tags desired := &resource.DesiredComposed{ Resource: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "ec2.aws.upbound.io/v1beta1", "kind": "Instance", }, }, } supports := SupportedManagedResource(desired, filter) // supports = true (EC2 instances support tags) // Check if an unsupported resource is in the filter unsupported := &resource.DesiredComposed{ Resource: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "unsupported.provider.io/v1beta1", "kind": "Custom", }, }, } supports = SupportedManagedResource(unsupported, filter) // supports = false (not in filter) ``` -------------------------------- ### Example Usage of ResolveIgnoreTags Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/function.md Demonstrates how to use ResolveIgnoreTags with different IgnoreTag configurations. It shows how to define ignore tags by value and by field path, and how the resulting TagUpdater might look. ```go ignoreTags := []v1beta1.IgnoreTag{ { Type: v1beta1.FromValue, Policy: v1beta1.ExistingTagPolicyReplace, Keys: []string{"aws:cloudformation:stack-name", "aws:cloudformation:stack-id"}, }, { Type: v1beta1.FromCompositeFieldPath, FromFieldPath: ptr("spec.parameters.externalTags"), Policy: v1beta1.ExistingTagPolicyRetain, }, } // Observed resource status contains: {"aws:cloudformation:stack-name": "my-stack", "Environment": "prod"} updater := f.ResolveIgnoreTags(ignoreTags, xr, observed, env) // updater.Replace contains: {"aws:cloudformation:stack-name": "my-stack"} // updater.Retain contains: tags from spec.parameters.externalTags found in observed ``` -------------------------------- ### Example Usage of MergeTags Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/tag-operations.md Demonstrates how to use the MergeTags function with a TagUpdater to modify resource tags. Shows the expected state of tags after merging. ```go // Existing tags in the resource: {"Environment": "staging", "Owner": "team-a"} tagUpdater := TagUpdater{ Retain: v1beta1.Tags{ "CostCenter": "12345", // Will be added (not present) }, Replace: v1beta1.Tags{ "Environment": "production", // Will overwrite "staging" "Team": "platform", // Will be added }, } err := MergeTags(desiredResource, tagUpdater) // Resource tags are now: {"Environment": "production", "Owner": "team-a", "CostCenter": "12345", "Team": "platform"} ``` -------------------------------- ### Example Go Text Template for Filters Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/generator.md A simplified Go text template demonstrating how to iterate through filter resources and access their GroupKind and Enabled fields to generate a Go map. ```go package filters func NewAWSResourceFilter() ResourceFilter { return ResourceFilter{ {{range .}} "{{.GroupKind}}": {{.Enabled}}, {{end}} } } ``` -------------------------------- ### Setting RunFunctionResponse Data in Go Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Provides Go code examples for constructing and populating a RunFunctionResponse. This includes setting the response status (success, warning, fatal), defining desired composed resources, and creating a response with a default TTL. ```go // Create response with default TTL rsp := response.To(req, response.DefaultTTL) // Set desired resources back err := response.SetDesiredComposedResources(rsp, desiredComposed) // Set result status response.Normalf(rsp, "Successfully Processed tags") // Success response.Warningf(rsp, "Some resources skipped") // Warning response.Fatal(rsp, errors.New("fatal error")) // Fatal ``` -------------------------------- ### AddTag Configuration Examples Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/types.md Illustrates two common ways to configure tag additions: using static tags with a 'Replace' policy, and extracting tags from a composite field path with a 'Retain' policy. ```yaml addTags: - type: FromValue policy: Replace tags: Environment: production Owner: platform-team - type: FromCompositeFieldPath fromFieldPath: spec.parameters.additionalTags policy: Retain ``` -------------------------------- ### Render Composition with Options Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Uses the Crossplane CLI to render a composition with specified options. Use this in a second terminal after starting the function. ```bash crossplane render composition.yaml -f options.yaml ``` -------------------------------- ### Accessing and Modifying Composed Resources Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Provides an example of how to retrieve all desired composed resources from a request and modify their state, such as updating tags in the spec. This is fundamental for managing composed resource configurations. ```go // Get all desired composed resources desiredComposed, err := request.GetDesiredComposedResources(req) for name, desired := range desiredComposed { // Access resource gvk := desired.Resource.GroupVersionKind() // Modify resource desired.Resource.SetValue("spec.forProvider.tags", tags) // Check metadata annotations := desired.Resource.GetAnnotations() labels := desired.Resource.GetLabels() } ``` -------------------------------- ### Example: Skip Tag Management using Annotation Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md YAML configuration demonstrating how to use the annotation 'tag-manager.fn.crossplane.io/ignore-resource' to skip tag management for an EC2 instance. ```yaml apiVersion: ec2.aws.upbound.io/v1beta1 kind: Instance metadata: name: my-instance annotations: tag-manager.fn.crossplane.io/ignore-resource: "true" spec: # Resource definition... ``` -------------------------------- ### Run Method for CLI Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/generator.md Executes the filter generation pipeline. This method handles logger initialization, generator setup, repository cloning, CRD examination, template rendering, and output generation. ```go func (c *CLI) Run() error ``` -------------------------------- ### Lint Code with Docker Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Use Docker to run a linter against the codebase, ensuring adherence to coding standards. Requires Docker to be installed. ```shell docker run --rm -v $(pwd):/app -v ~/.cache/golangci-lint/v2.6.1:/root/.cache -w /app golangci/golangci-lint:v2.6.1 golangci-lint run ``` -------------------------------- ### Example: Skip Tag Management using Label (Deprecated) Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md YAML configuration demonstrating the backward-compatible use of the label 'tag-manager.fn.crossplane.io/ignore-resource' to skip tag management for an EC2 instance. ```yaml apiVersion: ec2.aws.upbound.io/v1beta1 kind: Instance metadata: name: my-instance labels: tag-manager.fn.crossplane.io/ignore-resource: "true" spec: # Resource definition... ``` -------------------------------- ### Example Usage of ResolveAddTags Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/function.md Demonstrates how to use the ResolveAddTags function with different tag sources and policies. The 'Replace' policy overwrites existing tags, while 'Retain' preserves them. ```go addTags := []v1beta1.AddTag{ { Type: v1beta1.FromValue, Policy: v1beta1.ExistingTagPolicyReplace, Tags: map[string]string{ "Environment": "prod", "CostCenter": "12345", }, }, { Type: v1beta1.FromCompositeFieldPath, FromFieldPath: ptr("spec.parameters.tags"), Policy: v1beta1.ExistingTagPolicyRetain, }, } updater := f.ResolveAddTags(addTags, compositeResource, environment) // updater.Replace contains: {"Environment": "prod", "CostCenter": "12345"} // updater.Retain contains: tags from spec.parameters.tags ``` -------------------------------- ### Add Tags Consistently Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/README.md Example of how to add a consistent set of tags to all resources. This configuration uses the 'Replace' policy to ensure specified tags are always present. ```yaml addTags: - type: FromValue policy: Replace tags: ManagedBy: crossplane CostCenter: "12345" ``` -------------------------------- ### Run Function Service Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/cli.md Executes the function service with the specified CLI configuration. This method sets up logging, initializes the function, and starts the gRPC server with configured options for listening, TLS, and message size. ```go func (c *CLI) Run() error { // ... implementation details ... } ``` ```go // Create CLI instance from environment and flags ctx := kong.Parse(&CLI{}) // Run the service if err := ctx.Run(); err != nil { log.Fatal(err) } ``` -------------------------------- ### Example Usage of ResolveRemoveTags Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/function.md Demonstrates how to use the ResolveRemoveTags function with different RemoveTag configurations. It shows how to define tags to remove directly and by referencing a field path in the composite resource. ```go removeTags := []v1beta1.RemoveTag{ { Type: v1beta1.FromValue, Keys: []string{"temporary-tag", "debug-flag"}, }, { Type: v1beta1.FromCompositeFieldPath, FromFieldPath: ptr("spec.parameters.tagsToClean"), }, } keysToRemove := f.ResolveRemoveTags(removeTags, xr, env) // keysToRemove = []string{"temporary-tag", "debug-flag", ...any keys from spec.parameters.tagsToClean} ``` -------------------------------- ### Complex Multi-Source Tagging Strategy with Function Tag Manager Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/integration-examples.md This example demonstrates a comprehensive tagging strategy using the Function Tag Manager. It combines tags from environment data, composition values, composite resource fields, and department defaults, while also specifying tags to ignore and remove. ```yaml apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: complex-tagging-strategy spec: compositeTypeRef: apiVersion: infrastructure.example.com/v1 kind: CompleteEnvironment mode: Pipeline environment: data: platformTags: PlatformVersion: "2.0" ComplianceFramework: "SOC2" externallyManagedKeys: - "aws:service:account" - "iam:permission-boundary" pipeline: - step: create-resources functionRef: name: infrastructure-builder - step: comprehensive-tagging functionRef: name: crossplane-contrib-function-tag-manager input: apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: # 1. Environment-provided platform baseline (non-negotiable) - type: FromEnvironmentFieldPath fromFieldPath: platformTags policy: Replace # 2. Composition-specific platform tags (can override user tags) - type: FromValue policy: Replace tags: CompositionVersion: "1.5" CreatedBy: Crossplane Recoverable: "true" # 3. User-provided tags (preserved if already set) - type: FromCompositeFieldPath fromFieldPath: spec.parameters.customTags policy: Retain # 4. Department-level default tags - type: FromCompositeFieldPath fromFieldPath: spec.parameters.departmentDefaults policy: Retain ignoreTags: # 1. Preserve AWS-managed tags - type: FromValue policy: Replace keys: - aws:cloudformation:stack-name - aws:cloudformation:stack-id # 2. Preserve externally managed tags from environment - type: FromEnvironmentFieldPath fromFieldPath: externallyManagedKeys policy: Replace removeTags: # 1. Remove deprecated tags - type: FromValue keys: - deprecated-owner - old-version - temp-testing # 2. Remove tags specified for cleanup - type: FromCompositeFieldPath fromFieldPath: spec.parameters.tagsToRemove ``` -------------------------------- ### Example Usage of RemoveTags Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/tag-operations.md Illustrates the usage of the RemoveTags function to delete specific tag keys from a resource. Shows the resulting tags after removal, including handling of non-existent keys. ```go // Resource tags before: {"Environment": "prod", "Owner": "team-a", "temporary": "cleanup"} keysToRemove := []string{"temporary", "debug"} err := RemoveTags(desiredResource, keysToRemove) // Resource tags after: {"Environment": "prod", "Owner": "team-a"} // "debug" was not present, so it's silently skipped ``` -------------------------------- ### Accessing RunFunctionRequest Data in Go Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Provides Go code examples for retrieving various pieces of information from the RunFunctionRequest object, such as function input, observed/desired resources, context, and metadata. ```go // Get the function input input := &v1beta1.ManagedTags{} err := request.GetInput(req, input) // Get the observed composite resource oxr, err := request.GetObservedCompositeResource(req) // Get observed and desired composed resources observedComposed, err := request.GetObservedComposedResources(req) desiredComposed, err := request.GetDesiredComposedResources(req) // Get context value envValue, ok := request.GetContextKey(req, fncontext.KeyEnvironment) // Get metadata tag := req.GetMeta().GetTag() ``` -------------------------------- ### Dynamic Tag Inheritance with Parent Resources Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/integration-examples.md This example shows how to configure the tag manager to inherit tags from parent resources and add layer-specific and role-based tags. Use this when child resources need to reflect parent configurations or roles. ```yaml apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: hierarchical-tagging spec: compositeTypeRef: apiVersion: hierarchy.example.com/v1 kind: ApplicationCluster mode: Pipeline pipeline: - step: setup functionRef: name: cluster-setup - step: inherit-and-augment functionRef: name: crossplane-contrib-function-tag-manager input: apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: # Inherit parent labels through spec - type: FromCompositeFieldPath fromFieldPath: spec.parameters.inheritFromParent policy: Retain # Add layer-specific tags - type: FromValue policy: Replace tags: LayerType: application DeploymentMethod: crossplane # Add resource role tags - type: FromCompositeFieldPath fromFieldPath: spec.parameters.roleBasedTags policy: Retain ``` -------------------------------- ### Specify External Tags to Preserve Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/integration-examples.md This example shows how to define a list of tag keys in the S3Bucket's spec that the tag-manager function should ignore, allowing external systems to manage these specific tags. ```yaml apiVersion: storage.example.com/v1 kind: S3Bucket metadata: name: my-bucket spec: parameters: externalTagKeys: - "compliance-scanned" - "security-approved" - "backup-enabled" ``` -------------------------------- ### Development Mode Startup Command Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/configuration.md Use this command for development mode with debug logging enabled and insecure gRPC communication. ```bash # Development mode with debug logging and insecure gRPC go run . --insecure --debug ``` -------------------------------- ### Install Function-Tag-Manager as a Crossplane Package Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Install the function-tag-manager by applying this YAML manifest to your Crossplane cluster. This defines the function as a Crossplane Package. ```yaml apiVersion: pkg.crossplane.io/v1 kind: Function metadata: name: crossplane-contrib-function-tag-manager spec: package: xpkg.upbound.io/crossplane-contrib/function-tag-manager:v0.8.1 ``` -------------------------------- ### Function Main Entry Point Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/cli.md The main function serves as the entry point for the function service. It parses command-line arguments, sets the program description, and executes the parsed CLI command, exiting with a fatal error if execution fails. ```go func main() ``` -------------------------------- ### Production Mode Startup Command with mTLS Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/configuration.md This command is used for production deployments with mutual TLS (mTLS) enabled, specifying certificate directory, network protocol, address, and maximum message size. ```bash # Production with mTLS go run . \ --tls-server-certs-dir=/etc/crossplane/tls \ --network=tcp \ --address=:9443 \ --max-recv-message-size=8 ``` -------------------------------- ### Accessing Composition Environment Variables Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Demonstrates how to retrieve and parse environment variables from the composition context using predefined keys. This is useful for loading configuration like common tags. ```go envValue, ok := request.GetContextKey(req, fncontext.KeyEnvironment) if ok { env := &unstructured.Unstructured{} err := resource.AsObject(envValue.GetStructValue(), env) // Now access environment fields envMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(env) tags := make(map[string]string) fieldpath.Pave(envMap).GetValueInto("commonTags", &tags) } ``` -------------------------------- ### Run Tests Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/README.md Command to execute tests and check code coverage. Run 'go test -cover ./...' to ensure the function's components are working as expected. ```bash go test -cover ./... ``` -------------------------------- ### Access Function Metadata Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Retrieve metadata such as the invocation tag and start time from the request object. This is useful for logging and debugging purposes. ```go // Get function metadata meta := req.GetMeta() // Access tag from Composition pipeline tag := meta.GetTag() // e.g., "manage-tags" // Timestamps started := meta.GetStartTime() ``` -------------------------------- ### CLI Main Entry Point Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt The main function serving as the entry point for the CLI application. ```Go func main() { // Main application setup and execution cli := &CLI{} if err := cli.Run(context.Background()); err != nil { log.Fatalf("CLI execution failed: %v", err) } } ``` -------------------------------- ### Get RemoveTag Type Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/types.md Method to retrieve the Type field of a RemoveTag configuration. It includes fallback logic to 'FromValue' if the Type field is unset. ```go func (a *RemoveTag) GetType() TagManagerType { return a.Type } ``` -------------------------------- ### Usage of ResourceFilter in Resource Check Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/resource-filtering.md Demonstrates how to create a ResourceFilter once and use it to check if a composed resource is supported for tag management within a loop. ```go resourceFilter := filters.NewResourceFilter() // Created once for name, desired := range desiredComposed { if SupportedManagedResource(desired, resourceFilter) { // Process this resource for tag management } } ``` -------------------------------- ### Push Crossplane Package to Upbound Marketplace Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Push the built Crossplane package to the Upbound Marketplace using the 'up' CLI. Requires authentication with the Upbound registry. ```shell up xpkg push xpkg.upbound.io/crossplane-contrib/function-tag-manager:v0.8.1 -f function-tag-manager.xpkg ``` -------------------------------- ### Preserve AWS CloudFormation Tags Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/README.md Example of ignoring specific AWS CloudFormation tags to prevent them from being modified or removed. This ensures that tags managed by CloudFormation are preserved. ```yaml ignoreTags: - type: FromValue keys: - aws:cloudformation:stack-name - aws:cloudformation:stack-id - aws:cloudformation:logical-id ``` -------------------------------- ### Project File Structure Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/README.md Overview of the project's directory and file organization. This helps in understanding the location of different components like the main entry point, function logic, and generated code. ```plaintext . ├── main.go # CLI and service startup ├── fn.go # Function pipeline implementation ├── tags.go # Tag operations and resolution ├── filter.go # Resource filtering ├── input/v1beta1/input.go # Type definitions ├── filters/ │ ├── filter.go # Filter initialization │ ├── generate.go # Code generation trigger │ ├── zz_provider-upjet-aws.go # AWS resource support (generated) │ └── zz_provider-upjet-azure.go # Azure resource support (generated) ├── cmd/generator/ │ ├── main.go # Generator CLI │ ├── crd.go # CRD examination │ └── render/render.go # Template rendering ├── package/ │ ├── input/ # Generated CRD manifests │ └── crds/ # Input manifest structure └── README.md # This file ``` -------------------------------- ### Get CRD Version Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/generator.md Extracts the served and storage version from a CustomResourceDefinition. Iterates through the CRD's versions and returns the first one where both Served and Storage are true. ```go func GetCRDVersion(crd extv1.CustomResourceDefinition) (extv1.CustomResourceDefinitionVersion, error) ``` -------------------------------- ### Dockerized Function Deployment Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/cli.md This Dockerfile demonstrates how to build and deploy the function as a Docker image. It includes multi-stage builds for a smaller final image and sets the entrypoint with necessary configuration flags. ```dockerfile FROM golang:1.25 AS builder COPY . /src WORKDIR /src RUN go build -o /function . FROM gcr.io/distroless/base:nonroot COPY --from=builder /function / ENTRYPOINT ["/function", "--tls-server-certs-dir=/tls", "--address=:9443"] ``` -------------------------------- ### Workflow for Regenerating AWS Resource Filters Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/generator.md Command-line instructions to navigate to the filters directory, run 'go generate', and review the generated filter file. This process involves cloning repositories, examining CRDs, and rendering output using a specified template. ```bash # Navigate to filters directory cd filters # Run code generation (invokes go generate) go generate ./... # This executes the generator which: # 1. Clones or uses existing provider-upjet-aws repository # 2. Examines all CRDs in package/crds directory # 3. Checks for spec.forProvider.tags field in each resource # 4. Renders the output using the aws.tmpl template # 5. Writes to zz_provider-upjet-aws.go # Review the generated file cat zz_provider-upjet-aws.go ``` -------------------------------- ### Build Docker Image Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Build a Docker image for the function. This image can then be used for local testing or deployment. ```shell docker build . --tag=function-tag-manager ``` -------------------------------- ### Running Function Tag Manager Locally Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/README.md These commands demonstrate how to run the function locally for development and production. Use the `--debug` flag for verbose logging during development and `--tls-server-certs-dir` for secure production deployments. ```bash # Development with debug logging go run . --insecure --debug ``` ```bash # Production with mTLS go run . --tls-server-certs-dir=/etc/crossplane/tls ``` -------------------------------- ### Build Crossplane Package with Embedded Image Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Create a Crossplane package (.xpkg) that embeds a previously built Docker image. Specify the package definition file and the output file name. ```shell crossplane xpkg build -f package --embed-runtime-image=function-tag-manager -o function-tag-manager.xpkg ``` -------------------------------- ### Run Function in Development Mode Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/cli.md Use this command for local testing with debug logging and insecure mode enabled. ```bash go run . --insecure --debug ``` -------------------------------- ### Crossplane Render Command Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/examples/configuration-aws-network/README.md Use the Crossplane CLI to render XR, composition, and function configurations, including observed resources. ```shell crossplane render xr.yaml composition.yaml functions.yaml --observed-resources observed-resources --include-full-xr ``` -------------------------------- ### Function SDK Go Dependencies Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Import the necessary gRPC packages from the function-sdk-go library. These packages provide helper functions for parsing request data, building response data, and managing context. ```go import ( fnv1 "github.com/crossplane/function-sdk-go/proto/v1" "github.com/crossplane/function-sdk-go" "github.com/crossplane/function-sdk-go/request" "github.com/crossplane/function-sdk-go/response" fncontext "github.com/crossplane/function-sdk-go/context" ) ``` -------------------------------- ### CLI Configuration Structure Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/cli.md Defines the structure for command-line interface configuration, including fields for debug logging, network settings, address, TLS certificates directory, security, and maximum received message size. ```go type CLI struct { Debug bool Network string Address string TLSCertsDir string Insecure bool MaxRecvMessageSize int } ``` -------------------------------- ### Run Tests and Check Coverage Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Execute all tests and report code coverage. This helps ensure code quality and identify areas needing more testing. ```shell go test -cover ./... ok github.com/crossplane-contrib/function-tag-manager 0.542s coverage: 68.6% of statements ok github.com/crossplane-contrib/function-tag-manager/cmd/generator 1.035s coverage: 43.2% of statements github.com/crossplane-contrib/function-tag-manager/cmd/generator/render coverage: 0.0% of statements github.com/crossplane-contrib/function-tag-manager/filters coverage: 0.0% of statements github.com/crossplane-contrib/function-tag-manager/input/v1beta1 coverage: 0.0% of statements ``` -------------------------------- ### Create Azure ProviderConfig Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/examples/configuration-azure-network/README.md Configure the Azure provider with credentials from the created secret. Ensure the namespace matches your secret's namespace. ```shell cat <<'EOF' | kubectl apply -f - apiVersion: azure.m.upbound.io/v1beta1 kind: ProviderConfig metadata: name: default namespace: default spec: credentials: source: Secret secretRef: name: azure-creds namespace: upbound-system key: creds EOF ``` -------------------------------- ### CLI Run Method Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt The Run method for the CLI type, executing commands. ```Go func (cli *CLI) Run(ctx context.Context) error { // CLI execution logic return nil } ``` -------------------------------- ### Cost Allocation Tags with Environment and Composite Fields Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/integration-examples.md Implement cost allocation and chargeback by defining organization-wide tags in the environment and project-specific tags in the composite resource. ```yaml apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: name: cost-allocation spec: compositeTypeRef: apiVersion: billing.example.com/v1 kind: ChargeableResource mode: Pipeline environment: data: organizationTags: Company: "ACME Corporation" CostCenter: "engineering" ChargebackModel: "department" pipeline: - step: create-infrastructure functionRef: name: infra-provisioner - step: apply-cost-tags functionRef: name: crossplane-contrib-function-tag-manager input: apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: # Organization-wide cost allocation tags - type: FromEnvironmentFieldPath fromFieldPath: organizationTags policy: Replace # Project-specific chargeback - type: FromCompositeFieldPath fromFieldPath: spec.parameters.billingTags policy: Retain # Budget owner contact - type: FromValue policy: Replace tags: BudgetAlert: "enabled" CostMonitoring: "cloudwatch" ``` ```yaml apiVersion: billing.example.com/v1 kind: ChargeableResource metadata: name: critical-database spec: parameters: billingTags: Project: "customer-portal" BudgetOwner: "john.smith@acme.com" AllowedSpend: "$5000" BillingPeriod: "monthly" ``` -------------------------------- ### Enable Debug Logging Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/cli.md Use the --debug or -d flags to enable debug-level logging output in addition to info-level logs. ```bash go run . --debug ``` ```bash go run . -d ``` -------------------------------- ### Configuring Tagging with Environment Variables Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/grpc-interface.md Shows how to configure the tag-resources step in a pipeline to load tags from environment variables. The 'commonTags' field is loaded from the context environment. ```yaml pipeline: - step: tag-resources functionRef: name: crossplane-contrib-function-tag-manager input: apiVersion: tag-manager.fn.crossplane.io/v1beta1 kind: ManagedTags addTags: - type: FromEnvironmentFieldPath fromFieldPath: commonTags # Loaded from context environment ``` -------------------------------- ### Set TLS Server Certs Directory via Environment Variable Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/api-reference/cli.md Demonstrates how to set the TLS server certificates directory using the TLS_SERVER_CERTS_DIR environment variable. The command-line flag takes precedence if both are specified. ```bash # Using environment variable export TLS_SERVER_CERTS_DIR=/etc/crossplane/tls go run . # Command-line flag takes precedence if both are specified TLS_SERVER_CERTS_DIR=/etc/crossplane/tls go run . --tls-server-certs-dir=/other/certs # Uses /other/certs ``` -------------------------------- ### Run Code Generation Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/README.md Execute code generation scripts. This is typically done before running tests or building. ```shell go generate ./... ``` -------------------------------- ### API Reference - CLI Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/GENERATION_SUMMARY.txt Documentation for the Command Line Interface (CLI), including type definitions, flag documentation, environment variable support, the Run method, and TLS configuration. ```APIDOC ## CLI Interface Documentation This document provides comprehensive details on the Command Line Interface (CLI) for the Function Tag Manager, including its structure, configuration, and operational methods. ### Core Components - **CLI type and fields**: Describes the structure and available fields for the CLI configuration. - **Flag documentation**: Exhaustive list and explanation of all available command-line flags. - **Environment variable support**: Details how environment variables can be used to configure the CLI. ### Methods - **Run()** - Description: Executes the main logic of the CLI based on provided arguments and configuration. - Usage: The primary method for invoking CLI operations. - **main() entry point** - Description: The entry point for the CLI application. ### Configuration - **TLS configuration**: Options for configuring Transport Layer Security for secure communication. ### Usage - **Usage examples for all modes**: Demonstrates how to use the CLI for various tasks and modes of operation. - **Error handling**: Documentation on potential errors and how they are handled by the CLI. ``` -------------------------------- ### Build Container Image Source: https://github.com/crossplane-contrib/function-tag-manager/blob/main/_autodocs/README.md Command to build the Docker container image for the function-tag-manager. Use 'docker build -t function-tag-manager:latest .' to create a local image tagged as 'latest'. ```bash docker build -t function-tag-manager:latest . ```