catch four more class reference forms
A params.pp is only ever reached by inherits and $class::var, so changing one resolved to no hosts at all. - index inherits, $class::var reads and create_resources() - match a defined type declared part-way along a line
This commit is contained in:
@@ -202,7 +202,8 @@ pluginsynced to every agent and is treated the same way.
|
||||
Finding what applies a class means searching two places, not one:
|
||||
|
||||
1. `.pp` files under `site/` and `modules/` for `include`, `contain`,
|
||||
`class { '...': }`, capitalised resource references and defined-type usage.
|
||||
`inherits`, `class { '...': }`, capitalised resource references,
|
||||
`create_resources()`, `$class::var` reads and defined-type usage.
|
||||
2. `hieradata/**/*.{yaml,eyaml}` for the class as a list item under
|
||||
`hiera_include:`. `profiles::base` declares
|
||||
`($hiera_include - $hiera_exclude).include` with a `unique` merge across the
|
||||
|
||||
@@ -17,11 +17,16 @@ import (
|
||||
var manifestRoots = []string{"site", "modules"}
|
||||
|
||||
var (
|
||||
commentRe = regexp.MustCompile(`(?m)#.*$`)
|
||||
includeRe = regexp.MustCompile(`\b(?:include|contain|require)\s*\(?\s*['"]?(?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)*)['"]?`)
|
||||
classParamRe = regexp.MustCompile(`\bclass\s*\{\s*['"](?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)*)['"]`)
|
||||
classRefRe = regexp.MustCompile(`\bClass\s*\[\s*['"](?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)*)['"]`)
|
||||
defineUseRe = regexp.MustCompile(`(?m)^\s*(?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)+)\s*\{`)
|
||||
commentRe = regexp.MustCompile(`(?m)#.*$`)
|
||||
includeRe = regexp.MustCompile(`\b(?:include|contain|require|inherits)\s*\(?\s*['"]?(?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)*)['"]?`)
|
||||
classParamRe = regexp.MustCompile(`\bclass\s*\{\s*['"](?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)*)['"]`)
|
||||
classRefRe = regexp.MustCompile(`\bClass\s*\[\s*['"](?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)*)['"]`)
|
||||
defineUseRe = regexp.MustCompile(`(?m)(?:^|[^\w:$.])(?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)+)\s*\{`)
|
||||
// $mod::params::thing reads a class variable, which is a dependency on the
|
||||
// class that declares it.
|
||||
scopeVarRe = regexp.MustCompile(`\$(?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)+)::[a-z_][a-z0-9_]*`)
|
||||
// create_resources('mod::type', ...) names a defined type in a string.
|
||||
createResRe = regexp.MustCompile(`create_resources\s*\(\s*['"](?:::)?([a-z][a-z0-9_]*(?:::[a-z0-9_]+)*)['"]`)
|
||||
resourceRefRe = regexp.MustCompile(`\b([A-Z][a-zA-Z0-9_]*(?:::[A-Z][a-zA-Z0-9_]*)+)\s*\[`)
|
||||
assetRe = regexp.MustCompile(`(?:template|epp|file)\s*\(\s*['"]([a-z0-9_]+/[^'"]+)['"]|puppet:///modules/([a-z0-9_]+/[^'"\s]+)`)
|
||||
hieraBlockRe = regexp.MustCompile(`(?m)^(hiera_include|hiera_exclude):\s*$((?:\n\s+-\s*\S+)*)`)
|
||||
@@ -153,7 +158,7 @@ func references(body string) []string {
|
||||
seen[name] = true
|
||||
}
|
||||
}
|
||||
for _, re := range []*regexp.Regexp{includeRe, classParamRe, classRefRe, defineUseRe} {
|
||||
for _, re := range []*regexp.Regexp{includeRe, classParamRe, classRefRe, defineUseRe, scopeVarRe, createResRe} {
|
||||
for _, m := range re.FindAllStringSubmatch(body, -1) {
|
||||
add(m[1])
|
||||
}
|
||||
|
||||
@@ -123,3 +123,23 @@ func TestParseHieraListsRegexFallback(t *testing.T) {
|
||||
t.Errorf("exclude = %v", exclude)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveInheritsScopeVarCreateResourcesAndInlineDefine(t *testing.T) {
|
||||
// Four reference forms a plain include grep misses: class inheritance,
|
||||
// a $class::var read, create_resources() naming a type in a string, and a
|
||||
// defined type declared part-way along a line.
|
||||
tests := map[string]string{
|
||||
"inherits": "profiles::inherited",
|
||||
"scope variable": "profiles::scopevar",
|
||||
"create_resources": "profiles::created",
|
||||
"inline define": "profiles::inline::thing",
|
||||
}
|
||||
want := []string{"k8s1", "k8s2", "web1"}
|
||||
for name, class := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if got := resolvedHosts(t, class); !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("%s = %v, want %v", class, got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
define profiles::created () {
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class profiles::inherited {
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
define profiles::inline::thing () {
|
||||
}
|
||||
@@ -1,4 +1,12 @@
|
||||
class profiles::leaf {
|
||||
$copied = $profiles::scopevar::thing
|
||||
create_resources('profiles::created', {})
|
||||
|
||||
case $copied {
|
||||
'x': { profiles::inline::thing { 'mid-line': } }
|
||||
default: {}
|
||||
}
|
||||
|
||||
file { '/tmp/leaf':
|
||||
content => template('profiles/leaf/x.erb'),
|
||||
source => 'puppet:///modules/profiles/leaf/y.txt',
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
class profiles::mid {
|
||||
class profiles::mid inherits profiles::inherited {
|
||||
include profiles::leaf
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class profiles::scopevar {
|
||||
$thing = 'x'
|
||||
}
|
||||
Reference in New Issue
Block a user