-
Notifications
You must be signed in to change notification settings - Fork 38
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
Resource name sanitization #108
Conversation
1674fc9
to
26a5641
Compare
rebased and squashed old commits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass, looks good in general. I think general comments
- seems like for every new entity that we support we'll need to add that set of rules. Seems like the right way to do it but yeh definitely a lot of bloat to the compiled dir since i believe these will end up there.
- Might just be me but while it does seem comprehensive, it also seems somewhat complex of a process. Specifically around the weighting (0 -> 100) of components and in the shortening func, it does a length subtraction vs. building from most important components up and hashing once it's exceeded the length.
Last point is also not really like a negative, just more of an observation so not a big deal if no one else has similar thoughts.
That's true. Ideally, this functionality will move into the compiler at some point. Another option is running it through a build tool to merge all the sanitization files into a single file that we include in the output. |
What do we do if we have like multiple clusters and install a controller on both. Is it on the plugin to label that resourceId cluster-resource? |
switch (params.loadBalancerType) { | ||
case 'application': | ||
lb = new aws.lb.LoadBalancer(`${appName}-${resourceId}-alb`, { | ||
name: `${appName}-${resourceId}`, | ||
name: lbName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also a general thing, we likely shouldnt set actual names of resources because then they cant get replaced if they change. We should be doing the validation on the resource id for pulumi i believe so that it autogenerates the name + some uuid for uniqueness if we ever need replacements.
let me know your thought on that, i think i added the name field, but i was going to remove it in my next pr because i noticed it could cause issues. We should likely see where else we do this
@@ -46,7 +47,10 @@ export const setupElasticacheCluster = ( | |||
retentionInDays: 0, | |||
}) | |||
|
|||
const clusterName = sanitizeClusterName(appName, dbName) | |||
// TODO: look into removing sanitizeClusterName when making other breaking changes to resource names | |||
const clusterName = sanitized( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, need to remove clustername as the actual name for this and memdb but lets maybe chat about that tomorrow
ab1e0ce
to
1207cab
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, other than the merge conflicts. I had a suggestion for a simplification, but it's not blocking. May want to get @jhsinger-klotho's quick glance too, since he took a more in-depth look a couple weeks back.
export function regexpMatch( | ||
description: string, | ||
pattern: RegExp, | ||
fix: FixFunc | undefined = undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small suggestion: I think all of the calls to this are basically:
regexpMatch(desc, /^P+$/, (n) => n.replace(/P/g, R))
... where P
is some pattern and R
is a replacement string. For example:
regexpMatch('', /^[\w-]+$/, (n) => n.replace(/[^\w-]/g, '-'))
If that's true, I think you could simplify this to just take the pattern and a replace char, and generate the validate
and FixFunc
from them:
regexpMatch('', /[^\w-]/, '-'))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true for a lot of them, but definitely not all.
yeah, LGTM and if the test are passing definitely a good starting point. The name issue looks to be resolved but we can continue to remove those if we find more |
Co-authored-by: ewucc <[email protected]>
Co-authored-by: Yuval Shavit <[email protected]>
3811237
to
be91a47
Compare
if entry.IsDir() { | ||
dirSuffix = "/" | ||
} | ||
path := strings.TrimSuffix(parentDir, "/") + "/" + entry.Name() + dirSuffix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use path.Join
instead of + "/" +
to be more platform agnostic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The separator is always a forward slash when reading from embed.FS
.
From the docs for go:embed
:
The //go:embed directive accepts multiple space-separated patterns for brevity, but it can also be repeated, to avoid very long lines when there are many patterns. The patterns are interpreted relative to the package directory containing the source file. The path separator is a forward slash, even on Windows systems. Patterns may not contain ‘.’ or ‘..’ or empty path elements, nor may they begin or end with a slash. To match everything in the current directory, use ‘*’ instead of ‘.’. To allow for naming files with spaces in their names, patterns can be written as Go double-quoted or back-quoted string literals.
https://pkg.go.dev/embed#:~:text=The%20//go%3Aembed%20directive%20accepts,back%2Dquoted%20string%20literals.
pkg/infra/pulumi_aws/plugin_iac.go
Outdated
if err != nil { | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't propagate the error like addFile
since err
is defined within the scope of this function (at the files.ReadDir
line).
pkg/infra/pulumi_aws/plugin_iac.go
Outdated
} | ||
} | ||
|
||
addDir("iac/sanitization", "**/*.{test,spec}.{ts,js}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I like this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be even better if those spec files existed. 😅
@@ -152,6 +154,50 @@ func (p Plugin) Transform(result *core.CompilationResult, deps *core.Dependencie | |||
addFile("iac/k8s/add_ons/external_dns/index.ts") | |||
addFile("iac/k8s/add_ons/index.ts") | |||
|
|||
addDir := func(dir string, exclusions ...string) { | |||
var unreadEntries []string | |||
dirContents, err := files.ReadDir(dir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this do something with err
if it's not nil?
unreadEntries = unreadEntries[1:] | ||
if strings.HasSuffix(entry, "/") { | ||
var childEntries []os.DirEntry | ||
childEntries, err = files.ReadDir(strings.TrimSuffix(entry, "/")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LIikewise, handling this err
|
Sanitizes AWS resource names in deploylib and related IAC files
Sanitizes AWS resource names in deploylib and related IAC files
updating tests after merge to main
Resolves #49 (minus the actual namespacing piece)
This PR adds sanitization for the identifiers of AWS resources specified for creation via Klotho's IAC layer. This change should not change any happy path identifiers (resource names or Pulumi URNs)
Resource names are generated using tagged string templates as in the following examples using the
sanitized()
tag function:When shortening resource names, raw text or template expressions of type
string
are not modified. Expressions of typeComponent
are shortened from left to right based on priority (default priority is100
) using theComponent
instance's configuredShorteningStrategy
. In the examples above, theh()
function returns aComponent
with aShorteningStrategy
that converts the supplied text into a 5 character truncated SHA256 hash.The process of generating a valid resource name is as follows:
Component
s from left to right ranked by priority until the name's length <=maxLength
.SanitizationRule
s and capture any violations.FixFunc
(if present) to resolve any issues.Standard checks