Skip to content

Commit

Permalink
feat: adds sanitization functions
Browse files Browse the repository at this point in the history
  • Loading branch information
fullykubed committed Oct 14, 2024
1 parent 9da809a commit 349db98
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 164 deletions.
4 changes: 2 additions & 2 deletions docs/data-sources/aws_tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
page_title: "pf_aws_tags Data Source - pf"
subcategory: ""
description: |-
Example data source
Provides the standard set of Panfactum resource tags for AWS resources
---

# pf_aws_tags (Data Source)

Example data source
Provides the standard set of Panfactum resource tags for AWS resources



Expand Down
4 changes: 2 additions & 2 deletions docs/data-sources/kube_labels.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
page_title: "pf_kube_labels Data Source - pf"
subcategory: ""
description: |-
Example data source
Provides the standard set of Panfactum resource labels for Kubernetes resources
---

# pf_kube_labels (Data Source)

Example data source
Provides the standard set of Panfactum resource labels for Kubernetes resources



Expand Down
26 changes: 26 additions & 0 deletions docs/functions/sanitize_aws_tags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "sanitize_aws_tags function - pf"
subcategory: ""
description: |-
Returns the AWS tags that have been sanitized of invalid characters
---

# function: sanitize_aws_tags





## Signature

<!-- signature generated by tfplugindocs -->
```text
sanitize_aws_tags(tags map of string) map of string
```

## Arguments

<!-- arguments generated by tfplugindocs -->
1. `tags` (Map of String) The AWS tags to sanitize

26 changes: 26 additions & 0 deletions docs/functions/sanitize_kube_labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "sanitize_kube_labels function - pf"
subcategory: ""
description: |-
Returns the Kubernetes labels that have been sanitized of invalid characters
---

# function: sanitize_kube_labels





## Signature

<!-- signature generated by tfplugindocs -->
```text
sanitize_kube_labels(labels map of string) map of string
```

## Arguments

<!-- arguments generated by tfplugindocs -->
1. `labels` (Map of String) The Kubernetes labels to sanitize

26 changes: 0 additions & 26 deletions docs/functions/test.md

This file was deleted.

9 changes: 3 additions & 6 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,12 @@ description: |-
<!-- schema generated by tfplugindocs -->
## Schema

### Required
### Optional

- `environment` (String) The name of the environment that you are currently deploying infrastructure to
- `extra_tags` (Map of String) Extra tags to apply to all resources
- `is_local` (Boolean) Whether the provider is being used a part of a local development deployment
- `region` (String) The name of the region that you are currently deploying infrastructure to
- `root_module` (String) The name of the root / top-level module that you are currently deploying infrastructure with
- `stack_commit` (String) The commit hash of the Panfactum Stack that you are currently using
- `stack_version` (String) The version of the Panfactum Stack that you are currently using

### Optional

- `extra_tags` (Map of String) Extra tags to apply to all resources
- `is_local` (Boolean) Whether the provider is being used a part of a local development deployment
45 changes: 24 additions & 21 deletions provider/aws_tags_data_source.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// SPDX-License-Identifier: Apache-2.0

package provider

Expand All @@ -10,7 +10,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"regexp"
)

/**************************************************************
Expand Down Expand Up @@ -39,7 +38,8 @@ func (d *awsTagsDataSource) Metadata(ctx context.Context, req datasource.Metadat

func (d *awsTagsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Example data source",
Description: "Provides the standard set of Panfactum resource tags for AWS resources",
MarkdownDescription: "Provides the standard set of Panfactum resource tags for AWS resources",

Attributes: map[string]schema.Attribute{
"tags": schema.MapAttribute{
Expand Down Expand Up @@ -91,26 +91,29 @@ func (d *awsTagsDataSource) Read(ctx context.Context, req datasource.ReadRequest
return
}

labels := map[string]attr.Value{
"panfactum.com/environment": sanitizeAWSTagValue(d.ProviderData.Environment),
"panfactum.com/stack-version": sanitizeAWSTagValue(d.ProviderData.StackVersion),
"panfactum.com/stack-commit": sanitizeAWSTagValue(d.ProviderData.StackCommit),
"panfactum.com/local": types.StringValue(d.ProviderData.IsLocal.String()),
"panfactum.com/root-module": sanitizeAWSTagValue(d.ProviderData.RootModule),
"panfactum.com/module": sanitizeAWSTagValue(data.Module),
tags := map[string]attr.Value{
"panfactum.com/local": types.StringValue(d.ProviderData.IsLocal.String()),
}

// Set the default tags from the provider
setAWSTag(tags, "panfactum.com/environment", d.ProviderData.Environment)
setAWSTag(tags, "panfactum.com/stack-version", d.ProviderData.StackVersion)
setAWSTag(tags, "panfactum.com/stack-commit", d.ProviderData.StackCommit)
setAWSTag(tags, "panfactum.com/root-module", d.ProviderData.RootModule)
setAWSTag(tags, "panfactum.com/module", data.Module)

// Allow the region to be overridden
trueRegion := d.ProviderData.Region
var region = d.ProviderData.Region
if !data.RegionOverride.IsNull() && !data.RegionOverride.IsUnknown() {
trueRegion = data.RegionOverride
region = data.RegionOverride
}
labels["panfactum.com/region"] = sanitizeAWSTagValue(trueRegion)
setAWSTag(tags, "panfactum.com/region", region)

// Iterate over the extra tags and set them one-by-one
for key, value := range (d.ProviderData.ExtraTags).Elements() {
strValue, ok := value.(types.String)
if ok {
labels[sanitizeAWSTagKey(key)] = sanitizeAWSTagValue(strValue)
setAWSTag(tags, key, strValue)
} else {
resp.Diagnostics.AddError(
"Invalid type found",
Expand All @@ -120,7 +123,7 @@ func (d *awsTagsDataSource) Read(ctx context.Context, req datasource.ReadRequest
}
}

data.Tags, _ = types.MapValue(types.StringType, labels)
data.Tags, _ = types.MapValue(types.StringType, tags)

// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
Expand All @@ -130,12 +133,12 @@ func (d *awsTagsDataSource) Read(ctx context.Context, req datasource.ReadRequest
Utility Functions
**************************************************************/

func sanitizeAWSTagKey(input string) string {
re := regexp.MustCompile(`[^a-zA-Z0-9.:/_@+=-]`)
return re.ReplaceAllString(input, ".")
func setAWSTag(tags map[string]attr.Value, key string, value types.String) {
if !value.IsNull() && !value.IsUnknown() {
tags[sanitizeAWSTagKey(key)] = sanitizeAWSTagValueWrapped(value)
}
}

func sanitizeAWSTagValue(input types.String) types.String {
re := regexp.MustCompile(`[^a-zA-Z0-9.:/_@+=-]`)
return types.StringValue(re.ReplaceAllString(input.ValueString(), "."))
func sanitizeAWSTagValueWrapped(input types.String) types.String {
return types.StringValue(sanitizeAWSTagValue(input.ValueString()))
}
60 changes: 19 additions & 41 deletions provider/kube_labels_data_source.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// SPDX-License-Identifier: Apache-2.0

package provider

Expand All @@ -10,9 +10,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"regexp"
"strings"
"unicode"
)

/**************************************************************
Expand Down Expand Up @@ -40,7 +37,8 @@ func (d *kubeLabelsDataSource) Metadata(ctx context.Context, req datasource.Meta

func (d *kubeLabelsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "Example data source",
Description: "Provides the standard set of Panfactum resource labels for Kubernetes resources",
MarkdownDescription: "Provides the standard set of Panfactum resource labels for Kubernetes resources",

Attributes: map[string]schema.Attribute{
"labels": schema.MapAttribute{
Expand Down Expand Up @@ -88,19 +86,21 @@ func (d *kubeLabelsDataSource) Read(ctx context.Context, req datasource.ReadRequ
}

labels := map[string]attr.Value{
"panfactum.com/environment": sanitizeKubeLabelValue(d.ProviderData.Environment),
"panfactum.com/region": sanitizeKubeLabelValue(d.ProviderData.Region),
"panfactum.com/stack-version": sanitizeKubeLabelValue(d.ProviderData.StackVersion),
"panfactum.com/stack-commit": sanitizeKubeLabelValue(d.ProviderData.StackCommit),
"panfactum.com/local": types.StringValue(d.ProviderData.IsLocal.String()),
"panfactum.com/root-module": sanitizeKubeLabelValue(d.ProviderData.RootModule),
"panfactum.com/module": sanitizeKubeLabelValue(data.Module),
"panfactum.com/local": types.StringValue(d.ProviderData.IsLocal.String()),
}

// Set the default labels from the provider
setKubeLabel(labels, "panfactum.com/environment", d.ProviderData.Environment)
setKubeLabel(labels, "panfactum.com/region", d.ProviderData.Region)
setKubeLabel(labels, "panfactum.com/stack-version", d.ProviderData.StackVersion)
setKubeLabel(labels, "panfactum.com/stack-commit", d.ProviderData.StackCommit)
setKubeLabel(labels, "panfactum.com/root-module", d.ProviderData.RootModule)
setKubeLabel(labels, "panfactum.com/module", data.Module)

for key, value := range (d.ProviderData.ExtraTags).Elements() {
strValue, ok := value.(types.String)
if ok {
labels[sanitizeKubeLabelKey(key)] = sanitizeKubeLabelValue(strValue)
labels[sanitizeKubeLabelKey(key)] = sanitizeKubeLabelValueWrapped(strValue)
} else {
resp.Diagnostics.AddError(
"Invalid type found",
Expand All @@ -120,34 +120,12 @@ func (d *kubeLabelsDataSource) Read(ctx context.Context, req datasource.ReadRequ
Utility Functions
**************************************************************/

// sanitizeKubeLabelValue performs the required sanitization steps:
// 1. Replaces any non-alphanumeric, '.', '_', or '-' characters with '.'
// 2. Ensures the string starts and ends with an alphanumeric character
func sanitizeKubeLabelValue(input types.String) types.String {
// Replace any non-alphanumeric, '.', '_', or '-' characters with '.'
re := regexp.MustCompile(`[^a-zA-Z0-9._-]`)
sanitized := re.ReplaceAllString(input.ValueString(), ".")

// Trim any leading or trailing non-alphanumeric characters
sanitized = strings.TrimFunc(sanitized, func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
})

return types.StringValue(sanitized)
func setKubeLabel(tags map[string]attr.Value, key string, value types.String) {
if !value.IsNull() && !value.IsUnknown() {
tags[sanitizeKubeLabelKey(key)] = sanitizeKubeLabelValueWrapped(value)
}
}

// sanitizeKubeLabelKey performs the required sanitization steps:
// 1. Replaces any non-alphanumeric, '.', '_', '-', or '/' characters with '.'
// 2. Ensures the string starts and ends with an alphanumeric character
func sanitizeKubeLabelKey(input string) string {
// Replace any non-alphanumeric, '.', '_', '-', or '/' characters with '.'
re := regexp.MustCompile(`[^a-zA-Z0-9._/-]`)
sanitized := re.ReplaceAllString(input, ".")

// Trim any leading or trailing non-alphanumeric characters
sanitized = strings.TrimFunc(sanitized, func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
})

return sanitized
func sanitizeKubeLabelValueWrapped(input types.String) types.String {
return types.StringValue(sanitizeKubeLabelValue(input.ValueString()))
}
13 changes: 7 additions & 6 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,27 @@ func (p *PanfactumProvider) Schema(ctx context.Context, req provider.SchemaReque
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"environment": schema.StringAttribute{
Required: true,
Optional: true,
Description: "The name of the environment that you are currently deploying infrastructure to",
MarkdownDescription: "The name of the environment that you are currently deploying infrastructure to",
},
"region": schema.StringAttribute{
Required: true,
Optional: true,
Description: "The name of the region that you are currently deploying infrastructure to",
MarkdownDescription: "The name of the region that you are currently deploying infrastructure to",
},
"root_module": schema.StringAttribute{
Required: true,
Optional: true,
Description: "The name of the root / top-level module that you are currently deploying infrastructure with",
MarkdownDescription: "The name of the root / top-level module that you are currently deploying infrastructure with",
},
"stack_version": schema.StringAttribute{
Required: true,
Optional: true,
Description: "The version of the Panfactum Stack that you are currently using",
MarkdownDescription: "The version of the Panfactum Stack that you are currently using",
},
"stack_commit": schema.StringAttribute{
Required: true,
Optional: true,
Description: "The commit hash of the Panfactum Stack that you are currently using",
MarkdownDescription: "The commit hash of the Panfactum Stack that you are currently using",
},
Expand Down Expand Up @@ -96,6 +96,7 @@ func (p *PanfactumProvider) DataSources(ctx context.Context) []func() datasource

func (p *PanfactumProvider) Functions(ctx context.Context) []func() function.Function {
return []func() function.Function{
NewLowercasedFunction,
NewSanitizeAWSTagsFunction,
NewSanitizeKubeLabelsFunction,
}
}
Loading

0 comments on commit 349db98

Please sign in to comment.