Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement autonaming configuration protocol #1919

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/run-acceptance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@ jobs:
with:
name: pulumi-${{ env.PROVIDER }}-provider.tar.gz
path: ${{ github.workspace }}/bin/provider.tar.gz
- name: Configure AWS Credentials
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is auto generated, we'll need to change it here: https://github.com/pulumi/ci-mgmt

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do this - I guess my first question is whether I should be configuring credentials here and why I'm the first one to need this. Should I be using some other place for end-2-end tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to do that for now. They already include upgrade tests and while they do not use any invokes right now, they might in the future and those need creds:

func TestE2eSnapshots(t *testing.T) {
t.Run("logGroup-0.94.0", func(t *testing.T) {
t.Parallel()
test := newAwsTest(t, filepath.Join("testdata", "logGroup"))
testUpgradeFrom(t, test, "0.94.0")
})
t.Run("webAcl-0.94.0", func(t *testing.T) {
t.Parallel()
test := newAwsTest(t, filepath.Join("testdata", "webAcl"))
testUpgradeFrom(t, test, "0.94.0")
})
}

(Just saw that the upgrade tests are missing -short flag, I'll add that separately)

Long term I'd like us to have a more standard test setup where we have a single go.mod on the root and then separate directories for tests in order to keep slower-running integration tests separate from unit tests. This would enable us to run unit tests without needing to remember -short or build tags. But that's all unrelated to your changes.

Copy link
Member Author

@mikhailshilkov mikhailshilkov Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working on CI in pulumi/ci-mgmt#1239 but also discussing offline what the best approach could be

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pulumi/ci-mgmt#1239 is typically how we'd unblock this, but we're trying to do a couple things right now in the opposite direction:

  • we want to reduce the number of exceptions for native providers in order to make it easier to consolidate them with bridged workflows
  • and we want to make CI tests more reproducible locally, which means reducing the reliance on CI-specific setup steps.

For those reasons I'll suggest an alternative approach. Basically just perform the auth in-process as part of your test's setup. Actually, before you do that maybe just plumb the environment variables through, since the provider should login for you? So the test would get an environmnet

Env: []string{"AWS_ROLE_SESSION_NAME=" + os.Getenv("PROVIDER"), "AWS_ROLE_TO_ASSUME=" + os.Getenv("AWS_CI_ROLE_ARN"), ...}

Otherwise, if you do need to perform the auth, something like this pseudocode:

cfg := aws.Config{
  Credentials: credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""),
  Region: region,
}

c := sts.NewFromConfig(cfg)
creds, err := c.AssumeRole(ctx, &sts.AssumeRoleInput{
  RoleArn:         aws.String(os.Getenv("AWS_CI_ROLE_ARN")),
  RoleSessionName: aws.String(os.Getenv("AWS_ROLE_SESSION_NAME")),
})
require.NoError(t, err)

// Set environment with creds

Then pass those environment variables to the e2e test via Env:, or (worse) if you're lazy use os.Setenv.

If provider/pkg/provider/provider_2e2_test.go is the only place where you need these credentials, then I suggest defining a helper there like loginToAWS(t). You can put it behind a sync.Once to prevent logging in more than you need to.

Give it a try, and if it turns into a rabbit hole we can merge the ci-mgmt PR and clean it up later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can give this a try... This would make it unusable in a local dev environment unless one replicates all env vars, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd personally vote for the ci-mgmt option because it doesn't mess with the local dev setup. The changes to ci-mgmt are not that big IMO and the aws-native test structure will have to change for the consolidation anyways

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer ci-mgmt too... I un-drafted that PR, happy to ship it and remove the CI change here after it percolates.

uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-region: ${{ env.AWS_REGION }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
role-duration-seconds: 3600
role-session-name: ${{ env.PROVIDER }}@githubActions
role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }}
- name: Test Provider Library
run: make test_provider
- name: Upload coverage reports to Codecov
Expand Down
75 changes: 61 additions & 14 deletions provider/pkg/autonaming/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,26 @@ type AutoNamingConfig struct {
RandomSuffixMinLength int `json:"randomSuffixMinLength"`
}

// EngineAutonamingConfiguration contains autonaming parameters passed to the provider from the engine.
type EngineAutonamingConfiguration struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, why are we not reusing the autonaming structs and enum from pu-sdk?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question. I started there but then went for keeping the autonaming module self-contained. It feels like a fairly complicated piece of "domain logic", so I wasn't sure I wanted to mix in RPC types. I'm not sure how much I bought by doing so - can be persuaded the other way.

RandomSeed []byte
AutonamingMode *EngineAutonamingMode
ProposedName string
}

// EngineAutonamingMode is the mode of autonaming to apply to the resource.
type EngineAutonamingMode int32

const (
EngineAutonamingModePropose EngineAutonamingMode = iota
EngineAutonamingModeEnforce
EngineAutonamingModeDisable
)

func ApplyAutoNaming(
spec *metadata.AutoNamingSpec,
urn resource.URN,
randomSeed []byte,
engineAutonaming EngineAutonamingConfiguration,
olds,
news resource.PropertyMap,
config *AutoNamingConfig,
Expand All @@ -27,11 +43,13 @@ func ApplyAutoNaming(
return nil
}
// Auto-name fields if not already specified
val, err := getDefaultName(randomSeed, urn, spec, olds, news, config)
val, ok, err := getDefaultName(urn, engineAutonaming, spec, olds, news, config)
if err != nil {
return err
}
news[resource.PropertyKey(spec.SdkName)] = val
if ok {
news[resource.PropertyKey(spec.SdkName)] = *val
}
return nil
}

Expand All @@ -41,29 +59,57 @@ func ApplyAutoNaming(
// based on its URN name, It ensures the name meets the length constraints, if known.
// Defaults to the name followed by 7 random hex characters separated by a '-'.
func getDefaultName(
randomSeed []byte,
urn resource.URN,
engineAutonaming EngineAutonamingConfiguration,
autoNamingSpec *metadata.AutoNamingSpec,
olds,
news resource.PropertyMap,
config *AutoNamingConfig,
) (resource.PropertyValue, error) {
) (*resource.PropertyValue, bool, error) {
mikhailshilkov marked this conversation as resolved.
Show resolved Hide resolved
sdkName := autoNamingSpec.SdkName

// Prefer explicitly specified name
if v, ok := news[resource.PropertyKey(sdkName)]; ok {
return v, nil
return &v, true, nil
}

// Fallback to previous name if specified/set.
if v, ok := olds[resource.PropertyKey(sdkName)]; ok {
return v, nil
return &v, true, nil
}

// Generate naming trivia for the resource.
namingTriviaApplies, namingTrivia, err := CheckNamingTrivia(sdkName, news, autoNamingSpec.TriviaSpec)
if err != nil {
return resource.PropertyValue{}, err
return nil, false, err
}

if engineAutonaming.AutonamingMode != nil {
switch *engineAutonaming.AutonamingMode {
case EngineAutonamingModeDisable:
return nil, false, nil
case EngineAutonamingModeEnforce:
v := resource.NewStringProperty(engineAutonaming.ProposedName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we also validate the proposed name against the autoNamingSpec? I'm assuming that in the current case if the engineAutonaming.ProposedName > autoNamingSpec.MaxLength then the error will be thrown by the AWS service?

Same question for the naming trivia. If that is a requirement should we error here early?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the intended semantics of enforce, as described in the spec. It can be used to overcome an erroneous autonaming configuration of the provider and override it to follow through to the AWS API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is gonna be tricky for users right now. After reading pulumi/pulumi#17592 I couldn't find a way users could configure to shorten a logical name. IMO one of the reasons users would want to configure the autonaming behavior in aws-native is to get around naming constraints that are missing from the CFN schema. Usually that's a missing maxLength constraint.

A substring expression would be great for autonaming. Something like this maybe?${substr(name, 56)}-${alphanum(7)}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, they can't shorten a logical name right now. I haven't seen this concern anywhere in the original issue or RFC discussion, but if it comes up often enough, we can add it later. The good news is that it will then work for all providers equally, not just AWS Native.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

. It can be used to overcome an erroneous autonaming configuration of the provider and override it to follow through to the AWS API.

Ok so it's like an escape hatch that users can use until the upstream bug is fixed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is an escape hatch too. More broadly, a lot of users expressed strong opinions that they want Pulumi to stop mangling with names, period. Now they can do that easily and we guarantee that users have full control.

return &v, true, nil
case EngineAutonamingModePropose:
proposedName := engineAutonaming.ProposedName

// Apply naming trivia to the generated name.
if namingTriviaApplies {
proposedName = ApplyTrivia(namingTrivia, proposedName)
}

// Validate the proposed name against the length constraints.
if autoNamingSpec.MaxLength > 0 && len(proposedName) > autoNamingSpec.MaxLength {
return nil, false, fmt.Errorf("proposed name %q exceeds max length of %d", proposedName, autoNamingSpec.MaxLength)
}
if autoNamingSpec.MinLength > 0 && len(proposedName) < autoNamingSpec.MinLength {
return nil, false, fmt.Errorf("proposed name %q is shorter than min length of %d", proposedName, autoNamingSpec.MinLength)
}

v := resource.NewStringProperty(proposedName)
return &v, true, nil
}
}

var autoTrim bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way that we can get the new engine autonaming to work with the existing autoNaming config? It seems like it could work with EngineAutonamingModePropose. And then maybe we should throw errors if you try to configure it with Enforce or Disable?

"autoNaming": {
Description: "The configuration for automatically naming resources.",
TypeSpec: pschema.TypeSpec{Ref: "#/types/aws-native:config:AutoNaming"},
},

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My original take was a no, but now I think I misunderstood autoTrim. It could potentially apply to the Propose mode. randomSuffixMinLength won't work because the suffix (or prefix, or whatever format) is already baked into the proposed name.

Copy link
Member Author

@mikhailshilkov mikhailshilkov Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm still not sure about autoTrim. Do we have any docs about what its supposed to do exactly? Reading the code, its semantics is roughly "if a random suffix makes the generated name too long, we can trim that random suffix down to N characters, where N is either 1 or whatever the user configured". I don't think there is any way to apply that to the proposed name, given it has an unknown structure. I assume we don't want to be trimming non-random portions of the name, and there is no way to ensure the min suffix length rule.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without/preautoTrim the behavior was to allow the random suffix to be as little as 1 character if that allowed the name to fit within the maxLength requirements.

autoTrim introduced a couple of new behaviors.

  1. randomSuffixMinLength could be used to enforce a minimum length of the random suffix
  2. autoTrim: true. If the length of the name exceeded the maxLength (including the random suffix) then the name would be trimmed to fix within the maxLength. The part of the name that is trimmed is taken from the middle of the name in order to keep uniqueness.

It sounds like the randomSuffixMinLength might conflict with the new engine functionality. In that case we should throw an error if both are used. Since autoTrim removes from the middle it's possible it could work with the new engine behavior, but I think it would also be fine if these two features are mutually exclusive for now (especially if the autotrim behavior could be added to the engine)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to what Cory said.
Are we able to make a distinction between whether engine level autonaming is configured for the stack/provider or only for a certain resource.

I feel like autoTrim + stack/provider level autonaming config should be an invalid case, but autoTrim + resource level autonaming config should be valid because it is essentially an escape hatch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we able to make a distinction between whether engine level autonaming is configured for the stack/provider or only for a certain resource?

No

I feel like autoTrim + stack/provider level autonaming config should be an invalid case, but autoTrim + resource level autonaming config should be valid because it is essentially an escape hatch.

Could you please explain why this distinction? If a user configures a pattern like ${stack}-${name}-${hex(6)} on the provider level for all AWS Native resources vs. does so for a give aws-native:foo:Bar - how does that change the expectation of the user of whether some middle part of the generated name will be trimmed or not?

In any case, the question is a bit hypothetical because the provider can't tell the difference with the current design. I think I'm inclined to do the following for Propose mode:

  1. If RandomSuffixMinLength is configured, throw an error, we can't do anything with it.
  2. If AutoTrim is true and autoNamingSpec.MaxLength is defined, call trimName(ProposedName, autoNamingSpec.MaxLength) and hope it does what the user wanted.

But we can also keep it simple and throw an error for now.

Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine for now to just say that you can't configure both the engine autonaming and the provider autoName config and throw an error/warning if you have explicitly configured both.

I can create an issue for supporting a autoTrim type feature in the engine, would that be in pu/pu?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added returning an error if both engine and provider configs are specified. Also, renamed a few types and variables to make it consistent and more clear.

I can create an issue for supporting a autoTrim type feature in the engine, would that be in pu/pu?

yes

Expand Down Expand Up @@ -94,7 +140,7 @@ func getDefaultName(
if left <= 0 && autoTrim {
autoTrimMaxLength := autoNamingSpec.MaxLength - namingTrivia.Length() - randomSuffixMinLength
if autoTrimMaxLength <= 0 {
return resource.PropertyValue{}, fmt.Errorf("failed to auto-generate value for %[1]q."+
return nil, false, fmt.Errorf("failed to auto-generate value for %[1]q."+
" Prefix: %[2]q is too large to fix max length constraint of %[3]d"+
" with required suffix length %[4]d. Please provide a value for %[1]q",
sdkName, prefix, autoNamingSpec.MaxLength, randomSuffixMinLength)
Expand All @@ -106,12 +152,12 @@ func getDefaultName(

if left <= 0 {
if namingTrivia.Length() > 0 {
return resource.PropertyValue{}, fmt.Errorf("failed to auto-generate value for %[1]q."+
return nil, false, fmt.Errorf("failed to auto-generate value for %[1]q."+
" Prefix: %[2]q is too large to fix max length constraint of %[3]d"+
" with required suffix %[4]q. Please provide a value for %[1]q",
sdkName, prefix, autoNamingSpec.MaxLength, namingTrivia.Suffix)
} else {
return resource.PropertyValue{}, fmt.Errorf("failed to auto-generate value for %[1]q."+
return nil, false, fmt.Errorf("failed to auto-generate value for %[1]q."+
" Prefix: %[2]q is too large to fix max length constraint of %[3]d. Please provide a value for %[1]q",
sdkName, prefix, autoNamingSpec.MaxLength)
}
Expand All @@ -123,17 +169,18 @@ func getDefaultName(
}

// Resource name is URN name + "-" + random suffix.
random, err := resource.NewUniqueName(randomSeed, prefix, randLength, maxLength, nil)
random, err := resource.NewUniqueName(engineAutonaming.RandomSeed, prefix, randLength, maxLength, nil)
if err != nil {
return resource.PropertyValue{}, err
return nil, false, err
}

// Apply naming trivia to the generated name.
if namingTriviaApplies {
random = ApplyTrivia(namingTrivia, random)
}

return resource.NewStringProperty(random), nil
v := resource.NewStringProperty(random)
return &v, true, nil
}

// trimName will trim the prefix to fit within the max length constraint.
Expand Down
115 changes: 95 additions & 20 deletions provider/pkg/autonaming/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ import (

func Test_getDefaultName(t *testing.T) {
const sdkName = "autoName"
p := func(v EngineAutonamingMode) *EngineAutonamingMode {
return &v
}
tests := []struct {
name string
minLength int
maxLength int
olds resource.PropertyMap
news resource.PropertyMap
err error
comparison func(t *testing.T, actual resource.PropertyValue) bool
name string
minLength int
maxLength int
olds resource.PropertyMap
news resource.PropertyMap
err error
comparison func(t *testing.T, actual *resource.PropertyValue) bool
engineAutonaming EngineAutonamingConfiguration
noName bool
}{
{
name: "Name specified explicitly",
Expand Down Expand Up @@ -63,6 +68,61 @@ func Test_getDefaultName(t *testing.T) {
maxLength: 13,
comparison: within(13, 13),
},
{
name: "Autoname with AutonamingMode=Propose",
engineAutonaming: EngineAutonamingConfiguration{
AutonamingMode: p(EngineAutonamingModePropose),
ProposedName: "proposed-name",
},
comparison: equals(resource.NewStringProperty("proposed-name")),
},
{
name: "Autoname with AutonamingMode=Enforce",
engineAutonaming: EngineAutonamingConfiguration{
AutonamingMode: p(EngineAutonamingModeEnforce),
ProposedName: "enforced-name",
},
comparison: equals(resource.NewStringProperty("enforced-name")),
},
{
name: "Autoname with AutonamingMode=Disable",
engineAutonaming: EngineAutonamingConfiguration{
AutonamingMode: p(EngineAutonamingModeDisable),
},
comparison: func(t *testing.T, actual *resource.PropertyValue) bool {
return actual == nil
},
noName: true,
},
{
name: "Autoname with Propose mode and max length constraints",
engineAutonaming: EngineAutonamingConfiguration{
AutonamingMode: p(EngineAutonamingModePropose),
ProposedName: "very-long-proposed-name",
},
maxLength: 10,
err: fmt.Errorf("proposed name %q exceeds max length of %d", "very-long-proposed-name", 10),
},
{
name: "Autoname with Propose mode and min length constraints",
engineAutonaming: EngineAutonamingConfiguration{
AutonamingMode: p(EngineAutonamingModePropose),
ProposedName: "too-short-proposed-name",
},
minLength: 25,
err: fmt.Errorf("proposed name %q is shorter than min length of %d", "too-short-proposed-name", 25),
},
{
name: "Autoname with Propose mode and trivia",
engineAutonaming: EngineAutonamingConfiguration{
AutonamingMode: p(EngineAutonamingModePropose),
ProposedName: "proposed-name",
},
news: resource.PropertyMap{
"flag": resource.NewBoolProperty(true),
},
comparison: equals(resource.NewStringProperty("proposed-name-trivia-value")),
},
}

urn := resource.URN("urn:pulumi:dev::test::test-provider:testModule:TestResource::myName")
Expand All @@ -73,16 +133,29 @@ func Test_getDefaultName(t *testing.T) {
SdkName: "autoName",
MinLength: tt.minLength,
MaxLength: tt.maxLength,
TriviaSpec: &metadata.NamingTriviaSpec{
Rule: &metadata.NamingRule{
Field: "flag",
Condition: &metadata.NamingCondition{
Predicate: metadata.NamingPredicateEquals,
Value: resource.NewBoolProperty(true),
},
},
Trivia: &metadata.NamingTrivia{
Suffix: "-trivia-value",
},
},
}
got, err := getDefaultName(nil, urn, autoNamingSpec, tt.olds, tt.news, nil)
got, has, err := getDefaultName(urn, tt.engineAutonaming, autoNamingSpec, tt.olds, tt.news, nil)
if tt.err != nil {
require.EqualError(t, err, tt.err.Error())
return
} else {
require.NoError(t, err)
require.Equal(t, tt.noName, !has)
}
if !tt.comparison(t, got) {
t.Errorf("getDefaultName() = %v for spec: %+v", got, autoNamingSpec)
t.Errorf("getDefaultName() = %v for spec: %+v", *got, autoNamingSpec)
}
t.Logf("getDefaultName() = %v for spec: %+v", got, autoNamingSpec)
})
Expand All @@ -100,7 +173,7 @@ func Test_getDefaultName_withAutoNameConfig(t *testing.T) {
olds resource.PropertyMap
news resource.PropertyMap
err error
comparison func(t *testing.T, actual resource.PropertyValue) bool
comparison func(t *testing.T, actual *resource.PropertyValue) bool
}{
{
name: "Name specified explicitly",
Expand Down Expand Up @@ -190,35 +263,37 @@ func Test_getDefaultName_withAutoNameConfig(t *testing.T) {
}

autoNameConfig := tt.autoNameConfig
got, err := getDefaultName(nil, urn, autoNamingSpec, tt.olds, tt.news, &autoNameConfig)
engineAutonaming := EngineAutonamingConfiguration{}
got, has, err := getDefaultName(urn, engineAutonaming, autoNamingSpec, tt.olds, tt.news, &autoNameConfig)
if tt.err != nil {
require.EqualError(t, err, tt.err.Error())
return
} else {
require.NoError(t, err)
require.True(t, has)
}
if !tt.comparison(t, got) {
t.Errorf("getDefaultName() = %v for spec: %+v", got, autoNamingSpec)
t.Errorf("getDefaultName() = %v for spec: %+v", *got, autoNamingSpec)
}
t.Logf("getDefaultName() = %v for spec: %+v", got, autoNamingSpec)
t.Logf("getDefaultName() = %v for spec: %+v", *got, autoNamingSpec)
})
}
}

func equals(expected resource.PropertyValue) func(t *testing.T, actual resource.PropertyValue) bool {
return func(t *testing.T, actual resource.PropertyValue) bool {
return expected == actual
func equals(expected resource.PropertyValue) func(t *testing.T, actual *resource.PropertyValue) bool {
return func(t *testing.T, actual *resource.PropertyValue) bool {
return expected == *actual
}
}

func startsWith(prefix string, randomLen int) func(t *testing.T, actual resource.PropertyValue) bool {
return func(t *testing.T, actual resource.PropertyValue) bool {
func startsWith(prefix string, randomLen int) func(t *testing.T, actual *resource.PropertyValue) bool {
return func(t *testing.T, actual *resource.PropertyValue) bool {
return assert.Regexp(t, fmt.Sprintf("^%s-[a-z0-9]{%d}", prefix, randomLen), actual.StringValue())
}
}

func within(min, max int) func(t *testing.T, value resource.PropertyValue) bool {
return func(t *testing.T, actual resource.PropertyValue) bool {
func within(min, max int) func(t *testing.T, value *resource.PropertyValue) bool {
return func(t *testing.T, actual *resource.PropertyValue) bool {
l := len(actual.V.(string))
return min <= l && l <= max
}
Expand Down
3 changes: 3 additions & 0 deletions provider/pkg/autonaming/semantics.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ func CheckNamingTrivia(sdkName string, props resource.PropertyMap, spec *metadat
if err != nil {
return false, nil, err
}
if !namingTriviaApplies {
return false, nil, nil
}
namingTrivia := *spec.Trivia

return namingTriviaApplies, &namingTrivia, nil
Expand Down
Loading
Loading