Skip to content

Commit

Permalink
feat: Implemented str_truncate_label() as a function.
Browse files Browse the repository at this point in the history
  • Loading branch information
skyzyx committed Mar 11, 2024
1 parent 098169b commit b1fa98d
Show file tree
Hide file tree
Showing 12 changed files with 434 additions and 116 deletions.
Binary file modified acc-coverage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
147 changes: 80 additions & 67 deletions acc-coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions corefuncprovider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,11 @@ func (p *coreFuncProvider) Functions(ctx context.Context) []func() function.Func
StrCamelFunction,
StrConstantFunction,
StrKebabFunction,
// StrIterativeReplaceFunction,
StrLeftpadFunction,
StrPascalFunction,
StrSnakeFunction,
StrTruncateLabelFunction,
}
}

Expand Down
134 changes: 134 additions & 0 deletions corefuncprovider/str_truncate_label_function.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright 2023-2024, Northwood Labs
// Copyright 2023-2024, Ryan Parman <[email protected]>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package corefuncprovider // lint:no_dupe

import (
"context"
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-framework/function"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/lithammer/dedent"
"github.com/northwood-labs/terraform-provider-corefunc/corefunc"
)

// Ensure the implementation satisfies the expected interfaces.
var _ function.Function = &strTruncateLabelFunction{}

type (
// strTruncateLabelFunction is the function implementation.
strTruncateLabelFunction struct{}
)

// StrTruncateLabelFunction is a method that exposes its paired Go function as a
// Terraform Function.
// https://developer.hashicorp.com/terraform/plugin/framework/functions/implementation
func StrTruncateLabelFunction() function.Function { // lint:allow_return_interface
return &strTruncateLabelFunction{}
}

func (f *strTruncateLabelFunction) Metadata(
ctx context.Context,
req function.MetadataRequest,
resp *function.MetadataResponse,
) {
tflog.Debug(ctx, "Starting StrTruncateLabel Function Metadata method.")

resp.Name = "str_truncate_label"

tflog.Debug(ctx, fmt.Sprintf("resp.Name = %s", resp.Name))

tflog.Debug(ctx, "Ending StrTruncateLabel Function Metadata method.")
}

// Definition defines the parameters and return type for the function.
func (f *strTruncateLabelFunction) Definition(
ctx context.Context,
req function.DefinitionRequest,
resp *function.DefinitionResponse,
) {
tflog.Debug(ctx, "Starting StrTruncateLabel Function Definition method.")

resp.Definition = function.Definition{
Summary: "Supports prepending a prefix to a label, while truncating them to meet the maximum " +
"length constraints.",
MarkdownDescription: strings.TrimSpace(dedent.Dedent(`
Supports prepending a prefix to a label, while truncating them
to meet the maximum length constraints. Useful when grouping labels with a
kind of prefix. Both the prefix and the label will be truncated if necessary.
Uses a “balancing” algorithm between the prefix and the label, so that each
section is truncated as a factor of how much space it takes up in the merged
string.
-> The motivation for this is in working with monitoring systems such
as New Relic and Datadog where there are hundreds of applications in a
monitoring “prod” account, and also hundreds of applications in a monitoring
“nonprod” account. This allows us to group lists of monitors together using a
shared prefix, but also truncate them appropriately to fit length
constraints for names.
Maps to the ` + linkPackage("TruncateLabel") + ` Go method, which can be used in
` + Terratest + `.
`)),
Parameters: []function.Parameter{
function.Int64Parameter{
Name: "max_length",
MarkdownDescription: "The maximum allowed length of the combined label. Minimum value is `1`.",
},
function.StringParameter{
Name: "prefix",
MarkdownDescription: "The prefix to prepend to the label.",
},
function.StringParameter{
Name: "label",
MarkdownDescription: "The label itself.",
},
},
Return: function.StringReturn{},
}

tflog.Debug(ctx, "Ending StrTruncateLabel Function Definition method.")
}

func (f *strTruncateLabelFunction) Run(ctx context.Context, req function.RunRequest, resp *function.RunResponse) {
tflog.Debug(ctx, "Starting StrTruncateLabel Function Run method.")

var (
maxLength int64
prefix string
label string
)

resp.Error = function.ConcatFuncErrors(req.Arguments.Get(ctx, &maxLength, &prefix, &label))
if resp.Error != nil {
return
}

if maxLength < 1 {
resp.Error = function.ConcatFuncErrors(
function.NewArgumentFuncError(0, "max_length must be at least 1"),
)

return
}

value := corefunc.TruncateLabel(maxLength, prefix, label)
resp.Error = function.ConcatFuncErrors(resp.Result.Set(ctx, value))

tflog.Debug(ctx, "Ending StrTruncateLabel Function Run method.")
}
8 changes: 8 additions & 0 deletions corefuncprovider/str_truncate_label_function_fixture.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output "label" {
value = provider::corefunc::str_truncate_label(
{{ .MaxLength }},
"{{ .Prefix }}",
"{{ .Label }}",
)
}
#=> {{ .Expected }}
88 changes: 88 additions & 0 deletions corefuncprovider/str_truncate_label_function_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2023-2024, Northwood Labs
// Copyright 2023-2024, Ryan Parman <[email protected]>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package corefuncprovider // lint:no_dupe

import (
"bytes"
"fmt"
"log"
"os"
"strings"
"testing"
"text/template"

"github.com/northwood-labs/terraform-provider-corefunc/testfixtures"

"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/tfversion"
)

func TestAccStrTruncateLabelFunction(t *testing.T) {
t.Parallel()

funcName := traceFuncName()

for name, tc := range testfixtures.TruncateLabelTestTable { // lint:no_dupe
fmt.Printf(
"=== RUN %s/%s\n",
strings.TrimSpace(funcName),
strings.TrimSpace(name),
)

buf := &bytes.Buffer{}
tmpl := template.Must(
template.ParseFiles("str_truncate_label_function_fixture.tftpl"),
)

// Minimum value for the provider is 1.
if tc.MaxLength == 0 {
tc.MaxLength += 1
}

err := tmpl.Execute(buf, tc)
if err != nil {
log.Fatalln(err)
}

if os.Getenv("PROVIDER_DEBUG") != "" {
fmt.Fprintln(os.Stderr, buf.String())
}

resource.UnitTest(t, resource.TestCase{
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.SkipBelow(
version.Must(version.NewVersion("1.7.999")),
),
},
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: providerConfig + buf.String(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckOutput("label", func() string {
if tc.Expected == "" {
return "…"
}

return tc.Expected
}()),
),
},
},
})
}
}
9 changes: 9 additions & 0 deletions examples/functions/corefunc_str_truncate_label/function.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "label" {
value = provider::corefunc::str_truncate_label(
64,
"NW-ZZZ-CLOUD-TEST-APP-CLOUD-PROD-CRIT",
"K8S Pods Not Running Deployment Check",
)
}

#=> NW-ZZZ-CLOUD-TEST-APP-CLOUD-PR…: K8S Pods Not Running Deploymen…
13 changes: 13 additions & 0 deletions examples/functions/corefunc_str_truncate_label/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_version = "~> 1.8"

required_providers {
corefunc = {
source = "northwood-labs/corefunc"
version = "~> 1.4"
}
}
}

# There are no configuration options
provider "corefunc" {}
Loading

0 comments on commit b1fa98d

Please sign in to comment.