puppet 4.10.1 → 4.10.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/ext/project_data.yaml +1 -1
- data/lib/puppet.rb +40 -28
- data/lib/puppet/application/agent.rb +1 -1
- data/lib/puppet/application/apply.rb +1 -1
- data/lib/puppet/application/cert.rb +1 -1
- data/lib/puppet/application/describe.rb +1 -1
- data/lib/puppet/application/device.rb +1 -1
- data/lib/puppet/application/doc.rb +3 -3
- data/lib/puppet/application/filebucket.rb +1 -1
- data/lib/puppet/application/inspect.rb +2 -2
- data/lib/puppet/application/lookup.rb +1 -1
- data/lib/puppet/application/master.rb +1 -1
- data/lib/puppet/application/resource.rb +7 -7
- data/lib/puppet/defaults.rb +1 -1
- data/lib/puppet/etc.rb +75 -39
- data/lib/puppet/face/ca.rb +1 -1
- data/lib/puppet/face/catalog.rb +1 -1
- data/lib/puppet/face/certificate.rb +1 -1
- data/lib/puppet/face/certificate_request.rb +1 -1
- data/lib/puppet/face/certificate_revocation_list.rb +1 -1
- data/lib/puppet/face/config.rb +1 -1
- data/lib/puppet/face/epp.rb +1 -1
- data/lib/puppet/face/facts.rb +1 -1
- data/lib/puppet/face/file.rb +1 -1
- data/lib/puppet/face/help.rb +1 -1
- data/lib/puppet/face/key.rb +1 -1
- data/lib/puppet/face/man.rb +2 -2
- data/lib/puppet/face/module.rb +1 -1
- data/lib/puppet/face/node.rb +1 -1
- data/lib/puppet/face/parser.rb +1 -1
- data/lib/puppet/face/plugin.rb +1 -1
- data/lib/puppet/face/report.rb +1 -1
- data/lib/puppet/face/resource.rb +1 -1
- data/lib/puppet/face/resource_type.rb +1 -1
- data/lib/puppet/face/status.rb +1 -1
- data/lib/puppet/feature/base.rb +1 -1
- data/lib/puppet/functions/eyaml_lookup_key.rb +16 -12
- data/lib/puppet/functions/hiera.rb +9 -2
- data/lib/puppet/functions/hiera_array.rb +9 -2
- data/lib/puppet/functions/hiera_hash.rb +10 -2
- data/lib/puppet/functions/hiera_include.rb +17 -3
- data/lib/puppet/functions/hocon_data.rb +6 -0
- data/lib/puppet/functions/json_data.rb +4 -0
- data/lib/puppet/functions/yaml_data.rb +4 -0
- data/lib/puppet/generate/models/type/type.rb +6 -5
- data/lib/puppet/generate/templates/type/pcore.erb +1 -1
- data/lib/puppet/module_tool/skeleton/templates/generator/examples/init.pp.erb +1 -1
- data/lib/puppet/parser/functions/create_resources.rb +8 -0
- data/lib/puppet/parser/scope.rb +2 -2
- data/lib/puppet/pops/adapters.rb +10 -4
- data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +0 -2
- data/lib/puppet/pops/evaluator/runtime3_support.rb +31 -0
- data/lib/puppet/pops/issues.rb +8 -0
- data/lib/puppet/pops/loader/loader.rb +4 -0
- data/lib/puppet/pops/loader/module_loaders.rb +0 -2
- data/lib/puppet/pops/loader/static_loader.rb +1 -1
- data/lib/puppet/pops/loader/type_definition_instantiator.rb +1 -1
- data/lib/puppet/pops/loader/typed_name.rb +1 -0
- data/lib/puppet/pops/loaders.rb +7 -15
- data/lib/puppet/pops/lookup/environment_data_provider.rb +1 -1
- data/lib/puppet/pops/lookup/hiera_config.rb +3 -1
- data/lib/puppet/pops/lookup/interpolation.rb +2 -1
- data/lib/puppet/pops/lookup/lookup_key.rb +1 -1
- data/lib/puppet/pops/lookup/module_data_provider.rb +10 -2
- data/lib/puppet/pops/lookup/sub_lookup.rb +10 -9
- data/lib/puppet/pops/parser/lexer2.rb +20 -3
- data/lib/puppet/pops/pcore.rb +2 -2
- data/lib/puppet/pops/resource/resource_type_impl.rb +2 -2
- data/lib/puppet/pops/semantic_error.rb +12 -0
- data/lib/puppet/pops/serialization/deserializer.rb +7 -4
- data/lib/puppet/pops/types/p_type_set_type.rb +2 -2
- data/lib/puppet/pops/types/string_converter.rb +5 -17
- data/lib/puppet/pops/types/type_set_reference.rb +1 -1
- data/lib/puppet/pops/validation/checker4_0.rb +4 -0
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
- data/lib/puppet/provider/nameservice.rb +12 -4
- data/lib/puppet/provider/package/yum.rb +8 -8
- data/lib/puppet/provider/user/useradd.rb +1 -1
- data/lib/puppet/reference/configuration.rb +1 -1
- data/lib/puppet/resource.rb +9 -11
- data/lib/puppet/resource/type_collection.rb +1 -0
- data/lib/puppet/type/exec.rb +32 -26
- data/lib/puppet/type/file/mode.rb +4 -0
- data/lib/puppet/util/character_encoding.rb +77 -74
- data/lib/puppet/util/monkey_patches.rb +3 -1
- data/lib/puppet/util/windows/api_types.rb +3 -0
- data/lib/puppet/util/windows/file.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +31 -7
- data/spec/integration/faces/documentation_spec.rb +2 -2
- data/spec/integration/parser/pcore_resource_spec.rb +15 -0
- data/spec/integration/resource/type_collection_spec.rb +6 -0
- data/spec/lib/puppet/face/1.0.0/huzzah.rb +1 -1
- data/spec/lib/puppet/face/basetest.rb +1 -1
- data/spec/lib/puppet/face/huzzah.rb +1 -1
- data/spec/lib/puppet/face/version_matching.rb +1 -1
- data/spec/lib/puppet_spec/character_encoding.rb +12 -0
- data/spec/lib/puppet_spec/compiler.rb +7 -0
- data/spec/shared_examples/rhel_package_provider.rb +10 -11
- data/spec/unit/application/resource_spec.rb +22 -1
- data/spec/unit/configurer/fact_handler_spec.rb +2 -1
- data/spec/unit/etc_spec.rb +361 -153
- data/spec/unit/functions/lookup_spec.rb +118 -2
- data/spec/unit/parser/functions/create_resources_spec.rb +47 -6
- data/spec/unit/parser/scope_spec.rb +8 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +40 -0
- data/spec/unit/pops/loaders/loaders_spec.rb +141 -79
- data/spec/unit/pops/lookup/interpolation_spec.rb +49 -9
- data/spec/unit/pops/lookup/lookup_spec.rb +32 -0
- data/spec/unit/pops/parser/lexer2_spec.rb +28 -0
- data/spec/unit/pops/types/p_object_type_spec.rb +1 -1
- data/spec/unit/pops/types/p_type_set_type_spec.rb +1 -1
- data/spec/unit/pops/types/string_converter_spec.rb +21 -0
- data/spec/unit/pops/validator/validator_spec.rb +43 -0
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +2 -0
- data/spec/unit/provider/nameservice_spec.rb +113 -3
- data/spec/unit/provider/user/useradd_spec.rb +13 -0
- data/spec/unit/resource/catalog_spec.rb +21 -0
- data/spec/unit/util/character_encoding_spec.rb +193 -52
- metadata +4 -2
@@ -2080,8 +2080,9 @@ describe "The lookup function" do
|
|
2080
2080
|
}
|
2081
2081
|
end
|
2082
2082
|
|
2083
|
-
it 'raises
|
2084
|
-
expect
|
2083
|
+
it 'raises a warning' do
|
2084
|
+
expect(lookup('mod_a::a')).to eql('value mod_a::a (from environment)')
|
2085
|
+
expect(warnings).to include(/hiera.yaml version 3 found at module root was ignored/)
|
2085
2086
|
end
|
2086
2087
|
end
|
2087
2088
|
|
@@ -2946,6 +2947,121 @@ describe "The lookup function" do
|
|
2946
2947
|
|
2947
2948
|
let(:env_data) { data_files }
|
2948
2949
|
|
2950
|
+
context 'and a module using eyaml with different options' do
|
2951
|
+
|
2952
|
+
let(:private_module_key) do
|
2953
|
+
<<-PKCS7.unindent
|
2954
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2955
|
+
MIIEogIBAAKCAQEAuqVpctipK4OMWM+RwKcd/mR4pg6qE3+ItPVC9TlvBrmDaN/y
|
2956
|
+
YZRjQR+XovXSGuy/CneSQ9Qss0Ff3FKAmEeH0qN0V47a81hgLpjhLCX1n+Ov7r1Q
|
2957
|
+
DC1ciTpVzHE4krN3rJ/RmDohitIqT1IYYhdcEdaMG9E26HIzn1QIwaDiYU3mfqWM
|
2958
|
+
8CZExa0CeIsEzHRLSxuMi/xX0ENImCRUzY9GH88Cu2gUhpKlbVzJmVqGPgp94pJY
|
2959
|
+
YM+SUb0XP1yRySpJMnVg98oCUrQO2OoE/Gax/djAi6hrJUzejPsEKdZ1yxM6OyJW
|
2960
|
+
NjWZYs8izAxBqm7pv1hx5+X7AIPqwZTMVrB7TQIDAQABAoIBAHIex13QOYeAlGSM
|
2961
|
+
7bpUtBMiTV6DItxvIyA5wen8ZvU+oqmSHDorp5BfB7E9Cm0qChkVSRot9fLYawtk
|
2962
|
+
anoxakuRY4ZRs3AMvipfkXYT854CckTP/cykQ6soPuOU6plQIEEtKtMf3/hoTjRX
|
2963
|
+
ps77J3FEtEAh6Kexg/zMPdpeS2xgULhk0P9ZQEg+JhLA5dq0p0nz3SBkuzcxei79
|
2964
|
+
+Za/Tg1osD0AINOajdvPnKxvlmWJN0+LpGwVjFNhkoUXPeDyvq0z2V/Uqwz4HP2I
|
2965
|
+
UGv4tz3SbzFc3Ie4lzgUZzCQgUK3u60pq1uyA6BRtxwdEmpn5v++jGXBGJZpWwcW
|
2966
|
+
UNblESUCgYEA4aTH9+LHsNjLPs2FmSc7hNjwHG1rAHcDXTX2ccySjRcQvH4Z7xBL
|
2967
|
+
di+SzZ2Tf8gSLycPRgRVCbrgCODpjoV2D5wWnyUHfWm4+GQxHURYa4UDx69tsSKE
|
2968
|
+
OTRASJo7/Mz0M1a6YzgCzVRM/TO676ucmawzKUY5OUm1oehtODAiZOcCgYEA08GM
|
2969
|
+
AMBOznys02xREJI5nLR6AveuTbIjF2efEidoxoW+1RrMOkcqaDTrJQ5PLM+oDDwD
|
2970
|
+
iPzVjnroSbwJzFB71atIg7b7TwltgkXy7wNTedO2cm5u/I0q8tY2Jaa4Mz8JUnbe
|
2971
|
+
yafvtS0/mY6A5k+8/2UIMFin2rqU9NC9EUPIo6sCgYBhOvAwELibq89osIbxB8bN
|
2972
|
+
5+0PUtbYzG/WqnoXb193DIlZr7zdFththPJtR4lXdo7fYqViNluuZahEKyZ5E2lc
|
2973
|
+
MJZO3VXs5LGf1wyS3/B55EdMtHs/6O+w9qL8pflTZb2UobqPJoOOltTWBoR24iwI
|
2974
|
+
y/r/vhLKbMini9AEdjlb4QKBgGdYsax4Lr4GCQ8ScSnmQ6ngRyAFo5MV2pyEnRTu
|
2975
|
+
GOuywKUe9AeJTgAXu5+VMT0Mh9aYv5zu0Ic+IvpBhIKr0RRCCR0Hg/VaA5Et9FeE
|
2976
|
+
RwxRMFz+2rn1Z72moDyV9pZEMJeHnknK5WmGEOEvtGczCWmX9Hwr+Jf+sc4dxfiU
|
2977
|
+
HWsLAoGAXWSX73p/6R4eRfF5zU2UFJPvDzhmwObAuvU4zKs9x7PMxZfvyt/eBCO1
|
2978
|
+
fj2+hIR72RxVuHbLApF1BT6gPVLtNdvaNuCs8YlHcnx/Oi088F0ni7fL/xYBUvaB
|
2979
|
+
7wTf188UJxP1ofVMZW00P4I9mR6BrOulv455gCwsmg2X7WtJU48=
|
2980
|
+
-----END RSA PRIVATE KEY-----
|
2981
|
+
PKCS7
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
let(:public_module_key) do
|
2985
|
+
<<-PKCS7.unindent
|
2986
|
+
-----BEGIN CERTIFICATE-----
|
2987
|
+
MIIC2TCCAcGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAAMCAXDTE3MDUzMTE2Mjc0
|
2988
|
+
M1oYDzIwNjcwNTE5MTYyNzQzWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
2989
|
+
CgKCAQEAuqVpctipK4OMWM+RwKcd/mR4pg6qE3+ItPVC9TlvBrmDaN/yYZRjQR+X
|
2990
|
+
ovXSGuy/CneSQ9Qss0Ff3FKAmEeH0qN0V47a81hgLpjhLCX1n+Ov7r1QDC1ciTpV
|
2991
|
+
zHE4krN3rJ/RmDohitIqT1IYYhdcEdaMG9E26HIzn1QIwaDiYU3mfqWM8CZExa0C
|
2992
|
+
eIsEzHRLSxuMi/xX0ENImCRUzY9GH88Cu2gUhpKlbVzJmVqGPgp94pJYYM+SUb0X
|
2993
|
+
P1yRySpJMnVg98oCUrQO2OoE/Gax/djAi6hrJUzejPsEKdZ1yxM6OyJWNjWZYs8i
|
2994
|
+
zAxBqm7pv1hx5+X7AIPqwZTMVrB7TQIDAQABo1wwWjAPBgNVHRMBAf8EBTADAQH/
|
2995
|
+
MB0GA1UdDgQWBBQkhoMgOyPzEe7tOOimNH2//PYF2TAoBgNVHSMEITAfgBQkhoMg
|
2996
|
+
OyPzEe7tOOimNH2//PYF2aEEpAIwAIIBATANBgkqhkiG9w0BAQUFAAOCAQEAhRWc
|
2997
|
+
Nz3PcUJllao5G/v4AyvjLgwB2JgjJgh6D3ILoOe9TrDSXD7ZV3F30vFae+Eztk86
|
2998
|
+
pmM8x57E0HsuuY+Owf6/hvELtwbzf9N/lc9ySZSogGFoQeJ8rnCJAQ0FaPjqb7AN
|
2999
|
+
xTaY9HTzr4dZG1f+sw32RUu2fDe7Deqgf85uMSZ1mtRTt9zvo8lMQxVA2nVOfwz2
|
3000
|
+
Nxf+qSNYSCtf0/6iwfzHy0qPjaJnywgBCi3Lg2IMSqGUatxzH+9HWrBgD+ZYxmDz
|
3001
|
+
2gW+EIU1Y/We/tbjIWaR1PD+IzeRJi5fHq60RKHPSdp7TGtV48bQRvyZXC7sVCRa
|
3002
|
+
yxfX1IGYhCDzbFRQNg==
|
3003
|
+
-----END CERTIFICATE-----
|
3004
|
+
PKCS7
|
3005
|
+
end
|
3006
|
+
|
3007
|
+
let(:module_keys_dir) do
|
3008
|
+
keys = tmpdir('keys')
|
3009
|
+
dir_contained_in(keys, {
|
3010
|
+
private_key_name => private_module_key,
|
3011
|
+
public_key_name => public_module_key
|
3012
|
+
})
|
3013
|
+
keys
|
3014
|
+
end
|
3015
|
+
|
3016
|
+
let(:private_module_key_path) { File.join(module_keys_dir, private_key_name) }
|
3017
|
+
let(:public_module_key_path) { File.join(module_keys_dir, public_key_name) }
|
3018
|
+
|
3019
|
+
let(:mod_a_files) do
|
3020
|
+
{
|
3021
|
+
'mod_a' => {
|
3022
|
+
'hiera.yaml' => <<-YAML.unindent,
|
3023
|
+
version: 5
|
3024
|
+
hierarchy:
|
3025
|
+
- name: EYaml
|
3026
|
+
path: common.eyaml
|
3027
|
+
lookup_key: eyaml_lookup_key
|
3028
|
+
options:
|
3029
|
+
pkcs7_private_key: #{private_module_key_path}
|
3030
|
+
pkcs7_public_key: #{public_module_key_path}
|
3031
|
+
YAML
|
3032
|
+
'data' => {
|
3033
|
+
'common.eyaml' => <<-YAML.unindent
|
3034
|
+
---
|
3035
|
+
# "%{lookup('a')} (from module)"
|
3036
|
+
mod_a::a: >
|
3037
|
+
ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEw
|
3038
|
+
DQYJKoZIhvcNAQEBBQAEggEAC+lvda8mX6XkgCBstNw4IQUDyFcS6M0mS9gZ
|
3039
|
+
ev4VBDeUK4AUNVnzzdbW0Mnj9LbqlpzFx96VGqSxsRBpe7BVD0kVo5jQsEMn
|
3040
|
+
nbrWOD1lvXYrXZMXBeD9xJbMbH5EiiFhbaXcEKRAVGaLVQKjXDENDQ/On+it
|
3041
|
+
1+wmmVwJynDJR0lsCz6dcSKvw6wnxBcv32qFyePvJuIf04CHMhaS4ykedYHK
|
3042
|
+
vagUn5uVXOv/8G0JPlZnQLyxjE0v0heb0Zj0mvcP2+Y5BSW50AQVrMWJNtdW
|
3043
|
+
aFEg6H5hpjduQfQh3iWVuDLnWhbP0sY2Grn5dTOxQP8aTDSsiTUcSeIAmjr/
|
3044
|
+
K8YRCjBMBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAjL7InlBjRuohLLcBx
|
3045
|
+
686ogCDkhCan8bCE7aX2nr75QtLF3q89pFIR4/NGl5+oGEO+qQ==]
|
3046
|
+
YAML
|
3047
|
+
}
|
3048
|
+
}
|
3049
|
+
}
|
3050
|
+
end
|
3051
|
+
|
3052
|
+
let(:populated_env_dir) do
|
3053
|
+
dir_contained_in(env_dir, DeepMerge.deep_merge!(environment_files, env_name => { 'modules' => mod_a_files }))
|
3054
|
+
env_dir
|
3055
|
+
end
|
3056
|
+
|
3057
|
+
it 'repeatedly finds data in environment and module' do
|
3058
|
+
expect(lookup(['array_a', 'mod_a::a', 'hash_a'])).to eql([
|
3059
|
+
['array_a[0]', 'array_a[1]'],
|
3060
|
+
"Encrypted value 'a' (from environment) (from module)",
|
3061
|
+
{'hash_aa'=>{'aaa'=>'Encrypted value hash_a.hash_aa.aaa (from environment)'}}])
|
3062
|
+
end
|
3063
|
+
end
|
3064
|
+
|
2949
3065
|
it 'finds data in the environment' do
|
2950
3066
|
expect(lookup('a')).to eql("Encrypted value 'a' (from environment)")
|
2951
3067
|
end
|
@@ -89,6 +89,15 @@ describe 'function for dynamically creating resources' do
|
|
89
89
|
expect(catalog.resource(:file, "/etc/foo")['ensure']).to eq('present')
|
90
90
|
end
|
91
91
|
|
92
|
+
it 'unrealized exported resources should not be added' do
|
93
|
+
# a compiled catalog is normally filtered on virtual resources
|
94
|
+
# here the compilation is performed unfiltered to be able to find the exported resource
|
95
|
+
# it is then asserted that the exported resource is also virtual (and therefore filtered out by a real compilation).
|
96
|
+
catalog = compile_to_catalog_unfiltered("create_resources('@@file', {'/etc/foo'=>{'ensure'=>'present'}})")
|
97
|
+
expect(catalog.resource(:file, "/etc/foo").exported).to eq(true)
|
98
|
+
expect(catalog.resource(:file, "/etc/foo").virtual).to eq(true)
|
99
|
+
end
|
100
|
+
|
92
101
|
it 'should be able to add exported resources' do
|
93
102
|
catalog = compile_to_catalog("create_resources('@@file', {'/etc/foo'=>{'ensure'=>'present'}}) realize(File['/etc/foo'])")
|
94
103
|
expect(catalog.resource(:file, "/etc/foo")['ensure']).to eq('present')
|
@@ -232,6 +241,9 @@ describe 'function for dynamically creating resources' do
|
|
232
241
|
end
|
233
242
|
|
234
243
|
describe 'when creating classes' do
|
244
|
+
let(:logs) { [] }
|
245
|
+
let(:warnings) { logs.select { |log| log.level == :warning }.map { |log| log.message } }
|
246
|
+
|
235
247
|
it 'should be able to create classes' do
|
236
248
|
catalog = compile_to_catalog(<<-MANIFEST)
|
237
249
|
class bar($one) {
|
@@ -245,12 +257,34 @@ describe 'function for dynamically creating resources' do
|
|
245
257
|
expect(catalog.resource(:class, "bar")).not_to be_nil
|
246
258
|
end
|
247
259
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
end
|
260
|
+
[:off, :warning].each do | strictness |
|
261
|
+
it "should warn if strict = #{strictness} and class is exported" do
|
262
|
+
Puppet[:strict] = strictness
|
263
|
+
collect_notices('class test{} create_resources("@@class", {test => {}})')
|
264
|
+
expect(warnings).to include(/Classes are not virtualizable/)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should error if strict = error and class is exported' do
|
269
|
+
Puppet[:strict] = :error
|
270
|
+
expect{
|
271
|
+
compile_to_catalog('class test{} create_resources("@@class", {test => {}})')
|
272
|
+
}.to raise_error(/Classes are not virtualizable/)
|
273
|
+
end
|
274
|
+
|
275
|
+
[:off, :warning].each do | strictness |
|
276
|
+
it "should warn if strict = #{strictness} and class is virtual" do
|
277
|
+
Puppet[:strict] = strictness
|
278
|
+
collect_notices('class test{} create_resources("@class", {test => {}})')
|
279
|
+
expect(warnings).to include(/Classes are not virtualizable/)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'should error if strict = error and class is virtual' do
|
284
|
+
Puppet[:strict] = :error
|
285
|
+
expect{
|
286
|
+
compile_to_catalog('class test{} create_resources("@class", {test => {}})')
|
287
|
+
}.to raise_error(/Classes are not virtualizable/)
|
254
288
|
end
|
255
289
|
|
256
290
|
it 'should be able to add edges' do
|
@@ -291,4 +325,11 @@ describe 'function for dynamically creating resources' do
|
|
291
325
|
}.to raise_error(Puppet::Error, /Syntax error at.*/)
|
292
326
|
end
|
293
327
|
end
|
328
|
+
|
329
|
+
def collect_notices(code)
|
330
|
+
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
331
|
+
compile_to_catalog(code)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
294
335
|
end
|
@@ -578,6 +578,14 @@ describe Puppet::Parser::Scope do
|
|
578
578
|
@scope.unset_ephemeral_var
|
579
579
|
expect(@scope["apple"]).to eq(nil)
|
580
580
|
end
|
581
|
+
|
582
|
+
it 'should store an undef in local scope and let it override parent scope' do
|
583
|
+
@scope['cloaked'] = 'Cloak me please'
|
584
|
+
@scope.new_ephemeral(true)
|
585
|
+
@scope['cloaked'] = nil
|
586
|
+
expect(@scope['cloaked']).to eq(nil)
|
587
|
+
end
|
588
|
+
|
581
589
|
it "should be created from a hash" do
|
582
590
|
@scope.ephemeral_from({ "apple" => :fruit, "strawberry" => :berry})
|
583
591
|
expect(@scope["apple"]).to eq(:fruit)
|
@@ -403,6 +403,11 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
403
403
|
end
|
404
404
|
|
405
405
|
context "on strings requiring boxing to Numeric" do
|
406
|
+
let(:logs) { [] }
|
407
|
+
let(:notices) { logs.select { |log| log.level == :notice }.map { |log| log.message } }
|
408
|
+
let(:warnings) { logs.select { |log| log.level == :warning }.map { |log| log.message } }
|
409
|
+
let(:debugs) { logs.select { |log| log.level == :debug }.map { |log| log.message } }
|
410
|
+
|
406
411
|
{
|
407
412
|
"'2' + '2'" => 4,
|
408
413
|
"'-2' + '2'" => 0,
|
@@ -426,6 +431,35 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
426
431
|
end
|
427
432
|
end
|
428
433
|
|
434
|
+
{
|
435
|
+
"'2' + 2" => 2,
|
436
|
+
"'4' - 2" => 4,
|
437
|
+
"'2' * 2" => 2,
|
438
|
+
"'2' / 1" => 2,
|
439
|
+
"'8' >> 1" => 8,
|
440
|
+
"'4' << 1" => 4,
|
441
|
+
"'10' % 3" => 10,
|
442
|
+
}.each do |source, coerced_val|
|
443
|
+
it "should warn about numeric coercion in '#{source}' when strict = warning" do
|
444
|
+
Puppet[:strict] = :warning
|
445
|
+
collect_notices(source)
|
446
|
+
expect(warnings).to include(/The string '#{coerced_val}' was automatically coerced to the numerical value #{coerced_val}/)
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should not warn about numeric coercion in '#{source}' if strict = off" do
|
450
|
+
Puppet[:strict] = :off
|
451
|
+
collect_notices(source)
|
452
|
+
expect(warnings).to_not include(/The string '#{coerced_val}' was automatically coerced to the numerical value #{coerced_val}/)
|
453
|
+
end
|
454
|
+
|
455
|
+
it "should error when finding numeric coercion in '#{source}' if strict = error" do
|
456
|
+
Puppet[:strict] = :error
|
457
|
+
expect { parser.evaluate_string(scope, source, __FILE__) }.to raise_error(
|
458
|
+
/The string '#{coerced_val}' was automatically coerced to the numerical value #{coerced_val}/
|
459
|
+
)
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
429
463
|
{
|
430
464
|
"'0888' + '010'" => :error,
|
431
465
|
"'0xWTF' + '010'" => :error,
|
@@ -1466,4 +1500,10 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
1466
1500
|
end
|
1467
1501
|
end
|
1468
1502
|
|
1503
|
+
def collect_notices(code)
|
1504
|
+
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
|
1505
|
+
parser.evaluate_string(scope, code, __FILE__)
|
1506
|
+
end
|
1507
|
+
end
|
1508
|
+
|
1469
1509
|
end
|
@@ -22,6 +22,16 @@ describe 'loader helper classes' do
|
|
22
22
|
expect(tn.name).to eq('foo::bar')
|
23
23
|
expect(tn.qualified?).to be_truthy
|
24
24
|
end
|
25
|
+
|
26
|
+
it 'TypedName converts name to lower case' do
|
27
|
+
tn = Puppet::Pops::Loader::TypedName.new(:type, '::Foo::Bar')
|
28
|
+
expect(tn.name_parts).to eq(['foo', 'bar'])
|
29
|
+
expect(tn.name).to eq('foo::bar')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'TypedName is case insensitive' do
|
33
|
+
expect(Puppet::Pops::Loader::TypedName.new(:type, '::Foo::Bar')).to eq(Puppet::Pops::Loader::TypedName.new(:type, '::foo::bar'))
|
34
|
+
end
|
25
35
|
end
|
26
36
|
|
27
37
|
describe 'loaders' do
|
@@ -88,7 +98,7 @@ describe 'loaders' do
|
|
88
98
|
loaders = Puppet::Pops::Loaders.new(empty_test_env)
|
89
99
|
|
90
100
|
expect(loaders.public_environment_loader()).to be_a(Puppet::Pops::Loader::SimpleEnvironmentLoader)
|
91
|
-
expect(loaders.public_environment_loader().to_s).to eql("(SimpleEnvironmentLoader 'environment
|
101
|
+
expect(loaders.public_environment_loader().to_s).to eql("(SimpleEnvironmentLoader 'environment')")
|
92
102
|
expect(loaders.private_environment_loader()).to be_a(Puppet::Pops::Loader::DependencyLoader)
|
93
103
|
expect(loaders.private_environment_loader().to_s).to eql("(DependencyLoader 'environment private' [])")
|
94
104
|
end
|
@@ -389,53 +399,13 @@ describe 'loaders' do
|
|
389
399
|
end
|
390
400
|
end
|
391
401
|
|
392
|
-
context 'loading
|
402
|
+
context 'loading' do
|
393
403
|
let(:env_name) { 'testenv' }
|
394
404
|
let(:environments_dir) { Puppet[:environmentpath] }
|
395
405
|
let(:env_dir) { File.join(environments_dir, env_name) }
|
396
406
|
let(:env) { Puppet::Node::Environment.create(env_name.to_sym, [File.join(populated_env_dir, 'modules')]) }
|
397
|
-
let(:
|
398
|
-
|
399
|
-
{
|
400
|
-
"name": "example/%1$s",
|
401
|
-
"version": "0.0.2",
|
402
|
-
"source": "git@github.com/example/example-%1$s.git",
|
403
|
-
"dependencies": [],
|
404
|
-
"author": "Bob the Builder",
|
405
|
-
"license": "Apache-2.0"%2$s
|
406
|
-
}
|
407
|
-
JSON
|
408
|
-
}
|
409
|
-
|
410
|
-
let(:env_dir_files) do
|
411
|
-
{
|
412
|
-
'modules' => {
|
413
|
-
'a' => {
|
414
|
-
'manifests' => {
|
415
|
-
'init.pp' => 'class a { notice(A::A) }'
|
416
|
-
},
|
417
|
-
'types' => {
|
418
|
-
'a.pp' => 'type A::A = Variant[B::B, String]',
|
419
|
-
'n.pp' => 'type A::N = C::C'
|
420
|
-
},
|
421
|
-
'metadata.json' => sprintf(metadata_json, 'a', ', "dependencies": [{ "name": "example/b" }]')
|
422
|
-
},
|
423
|
-
'b' => {
|
424
|
-
'types' => {
|
425
|
-
'b.pp' => 'type B::B = Variant[C::C, Float]',
|
426
|
-
'x.pp' => 'type B::X = A::A'
|
427
|
-
},
|
428
|
-
'metadata.json' => sprintf(metadata_json, 'b', ', "dependencies": [{ "name": "example/c" }]')
|
429
|
-
},
|
430
|
-
'c' => {
|
431
|
-
'types' => {
|
432
|
-
'c.pp' => 'type C::C = Integer'
|
433
|
-
},
|
434
|
-
'metadata.json' => sprintf(metadata_json, 'c', '')
|
435
|
-
},
|
436
|
-
}
|
437
|
-
}
|
438
|
-
end
|
407
|
+
let(:node) { Puppet::Node.new("test", :environment => env) }
|
408
|
+
let(:env_dir_files) {}
|
439
409
|
|
440
410
|
let(:populated_env_dir) do
|
441
411
|
dir_contained_in(environments_dir, env_name => env_dir_files)
|
@@ -443,46 +413,138 @@ describe 'loaders' do
|
|
443
413
|
env_dir
|
444
414
|
end
|
445
415
|
|
446
|
-
|
447
|
-
|
448
|
-
|
416
|
+
context 'non autoloaded types and functions' do
|
417
|
+
let(:env_dir_files) {
|
418
|
+
{
|
419
|
+
'modules' => {
|
420
|
+
'tstf' => {
|
421
|
+
'manifests' => {
|
422
|
+
'init.pp' => <<-PUPPET.unindent
|
423
|
+
class tstf {
|
424
|
+
notice(testfunc())
|
425
|
+
}
|
426
|
+
PUPPET
|
427
|
+
}
|
428
|
+
},
|
429
|
+
'tstt' => {
|
430
|
+
'manifests' => {
|
431
|
+
'init.pp' => <<-PUPPET.unindent
|
432
|
+
class tstt {
|
433
|
+
notice(assert_type(GlobalType, 23))
|
434
|
+
}
|
435
|
+
PUPPET
|
436
|
+
}
|
437
|
+
}
|
438
|
+
}
|
439
|
+
}
|
440
|
+
}
|
449
441
|
|
450
|
-
|
451
|
-
|
452
|
-
|
442
|
+
it 'finds the function from a module' do
|
443
|
+
expect(eval_and_collect_notices(<<-PUPPET.unindent, node)).to eq(['hello from testfunc'])
|
444
|
+
function testfunc() {
|
445
|
+
'hello from testfunc'
|
446
|
+
}
|
447
|
+
include 'tstf'
|
448
|
+
PUPPET
|
449
|
+
end
|
453
450
|
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
type = type.types[0]
|
461
|
-
expect(type.name).to eql('B::B')
|
462
|
-
type = type.resolved_type
|
463
|
-
expect(type).to be_a(Puppet::Pops::Types::PVariantType)
|
464
|
-
type = type.types[0]
|
465
|
-
expect(type.name).to eql('C::C')
|
466
|
-
type = type.resolved_type
|
467
|
-
expect(type).to be_a(Puppet::Pops::Types::PIntegerType)
|
451
|
+
it 'finds the type from a module' do
|
452
|
+
expect(eval_and_collect_notices(<<-PUPPET.unindent, node)).to eq(['23'])
|
453
|
+
type GlobalType = Integer
|
454
|
+
include 'tstt'
|
455
|
+
PUPPET
|
456
|
+
end
|
468
457
|
end
|
469
458
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
459
|
+
context 'types' do
|
460
|
+
let(:env_name) { 'testenv' }
|
461
|
+
let(:environments_dir) { Puppet[:environmentpath] }
|
462
|
+
let(:env_dir) { File.join(environments_dir, env_name) }
|
463
|
+
let(:env) { Puppet::Node::Environment.create(env_name.to_sym, [File.join(populated_env_dir, 'modules')]) }
|
464
|
+
let(:metadata_json) {
|
465
|
+
<<-JSON
|
466
|
+
{
|
467
|
+
"name": "example/%1$s",
|
468
|
+
"version": "0.0.2",
|
469
|
+
"source": "git@github.com/example/example-%1$s.git",
|
470
|
+
"dependencies": [],
|
471
|
+
"author": "Bob the Builder",
|
472
|
+
"license": "Apache-2.0"%2$s
|
473
|
+
}
|
474
|
+
JSON
|
475
|
+
}
|
478
476
|
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
477
|
+
let(:env_dir_files) do
|
478
|
+
{
|
479
|
+
'modules' => {
|
480
|
+
'a' => {
|
481
|
+
'manifests' => {
|
482
|
+
'init.pp' => 'class a { notice(A::A) }'
|
483
|
+
},
|
484
|
+
'types' => {
|
485
|
+
'a.pp' => 'type A::A = Variant[B::B, String]',
|
486
|
+
'n.pp' => 'type A::N = C::C'
|
487
|
+
},
|
488
|
+
'metadata.json' => sprintf(metadata_json, 'a', ', "dependencies": [{ "name": "example/b" }]')
|
489
|
+
},
|
490
|
+
'b' => {
|
491
|
+
'types' => {
|
492
|
+
'b.pp' => 'type B::B = Variant[C::C, Float]',
|
493
|
+
'x.pp' => 'type B::X = A::A'
|
494
|
+
},
|
495
|
+
'metadata.json' => sprintf(metadata_json, 'b', ', "dependencies": [{ "name": "example/c" }]')
|
496
|
+
},
|
497
|
+
'c' => {
|
498
|
+
'types' => {
|
499
|
+
'c.pp' => 'type C::C = Integer'
|
500
|
+
},
|
501
|
+
'metadata.json' => sprintf(metadata_json, 'c', '')
|
502
|
+
},
|
503
|
+
}
|
504
|
+
}
|
505
|
+
end
|
506
|
+
|
507
|
+
before(:each) do
|
508
|
+
Puppet.push_context(:loaders => Puppet::Pops::Loaders.new(env))
|
509
|
+
end
|
510
|
+
|
511
|
+
after(:each) do
|
512
|
+
Puppet.pop_context
|
513
|
+
end
|
514
|
+
|
515
|
+
it 'resolves types using the loader that loaded the type a -> b -> c' do
|
516
|
+
type = Puppet::Pops::Types::TypeParser.singleton.parse('A::A', Puppet::Pops::Loaders.find_loader('a'))
|
517
|
+
expect(type).to be_a(Puppet::Pops::Types::PTypeAliasType)
|
518
|
+
expect(type.name).to eql('A::A')
|
519
|
+
type = type.resolved_type
|
520
|
+
expect(type).to be_a(Puppet::Pops::Types::PVariantType)
|
521
|
+
type = type.types[0]
|
522
|
+
expect(type.name).to eql('B::B')
|
523
|
+
type = type.resolved_type
|
524
|
+
expect(type).to be_a(Puppet::Pops::Types::PVariantType)
|
525
|
+
type = type.types[0]
|
526
|
+
expect(type.name).to eql('C::C')
|
527
|
+
type = type.resolved_type
|
528
|
+
expect(type).to be_a(Puppet::Pops::Types::PIntegerType)
|
529
|
+
end
|
530
|
+
|
531
|
+
it 'will not resolve implicit transitive dependencies, a -> c' do
|
532
|
+
type = Puppet::Pops::Types::TypeParser.singleton.parse('A::N', Puppet::Pops::Loaders.find_loader('a'))
|
533
|
+
expect(type).to be_a(Puppet::Pops::Types::PTypeAliasType)
|
534
|
+
expect(type.name).to eql('A::N')
|
535
|
+
type = type.resolved_type
|
536
|
+
expect(type).to be_a(Puppet::Pops::Types::PTypeReferenceType)
|
537
|
+
expect(type.type_string).to eql('C::C')
|
538
|
+
end
|
539
|
+
|
540
|
+
it 'will not resolve reverse dependencies, b -> a' do
|
541
|
+
type = Puppet::Pops::Types::TypeParser.singleton.parse('B::X', Puppet::Pops::Loaders.find_loader('b'))
|
542
|
+
expect(type).to be_a(Puppet::Pops::Types::PTypeAliasType)
|
543
|
+
expect(type.name).to eql('B::X')
|
544
|
+
type = type.resolved_type
|
545
|
+
expect(type).to be_a(Puppet::Pops::Types::PTypeReferenceType)
|
546
|
+
expect(type.type_string).to eql('A::A')
|
547
|
+
end
|
486
548
|
end
|
487
549
|
end
|
488
550
|
|