puppet 4.7.1 → 4.8.0
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/Gemfile +0 -3
- data/MAINTAINERS +76 -0
- data/README.md +0 -6
- data/Rakefile +2 -2
- data/lib/puppet/agent.rb +3 -3
- data/lib/puppet/application/apply.rb +1 -1
- data/lib/puppet/configurer.rb +2 -2
- data/lib/puppet/data_providers.rb +1 -0
- data/lib/puppet/data_providers/data_adapter.rb +1 -0
- data/lib/puppet/data_providers/data_function_support.rb +1 -0
- data/lib/puppet/data_providers/function_env_data_provider.rb +1 -0
- data/lib/puppet/data_providers/function_module_data_provider.rb +1 -0
- data/lib/puppet/data_providers/hiera_config.rb +1 -0
- data/lib/puppet/data_providers/hiera_env_data_provider.rb +1 -0
- data/lib/puppet/data_providers/hiera_interpolate.rb +1 -0
- data/lib/puppet/data_providers/hiera_module_data_provider.rb +1 -0
- data/lib/puppet/data_providers/hiera_support.rb +1 -2
- data/lib/puppet/data_providers/json_data_provider_factory.rb +2 -0
- data/lib/puppet/data_providers/yaml_data_provider_factory.rb +2 -0
- data/lib/puppet/defaults.rb +20 -1
- data/lib/puppet/environments.rb +5 -2
- data/lib/puppet/face/catalog.rb +1 -1
- data/lib/puppet/face/epp.rb +57 -11
- data/lib/puppet/face/module/install.rb +6 -6
- data/lib/puppet/functions.rb +23 -24
- data/lib/puppet/functions/alert.rb +14 -0
- data/lib/puppet/functions/binary_file.rb +25 -0
- data/lib/puppet/functions/break.rb +22 -0
- data/lib/puppet/functions/contain.rb +33 -0
- data/lib/puppet/functions/crit.rb +14 -0
- data/lib/puppet/functions/debug.rb +14 -0
- data/lib/puppet/functions/emerg.rb +14 -0
- data/lib/puppet/functions/epp.rb +1 -1
- data/lib/puppet/functions/err.rb +14 -0
- data/lib/puppet/functions/find_file.rb +31 -0
- data/lib/puppet/functions/include.rb +21 -0
- data/lib/puppet/functions/info.rb +14 -0
- data/lib/puppet/functions/new.rb +1 -1
- data/lib/puppet/functions/next.rb +23 -0
- data/lib/puppet/functions/notice.rb +14 -0
- data/lib/puppet/functions/regsubst.rb +12 -16
- data/lib/puppet/functions/require.rb +37 -0
- data/lib/puppet/functions/return.rb +22 -0
- data/lib/puppet/functions/strftime.rb +35 -0
- data/lib/puppet/functions/warning.rb +14 -0
- data/lib/puppet/generate/models/type/type.rb +4 -0
- data/lib/puppet/generate/templates/type/pcore.erb +2 -1
- data/lib/puppet/indirector/face.rb +6 -1
- data/lib/puppet/network/http/error.rb +2 -2
- data/lib/puppet/network/http/handler.rb +2 -2
- data/lib/puppet/node/environment.rb +11 -0
- data/lib/puppet/parser/ast.rb +5 -0
- data/lib/puppet/parser/ast/pops_bridge.rb +17 -4
- data/lib/puppet/parser/compiler.rb +29 -1
- data/lib/puppet/parser/functions.rb +6 -0
- data/lib/puppet/parser/functions/assert_type.rb +1 -1
- data/lib/puppet/parser/functions/binary_file.rb +24 -0
- data/lib/puppet/parser/functions/break.rb +39 -0
- data/lib/puppet/parser/functions/contain.rb +7 -15
- data/lib/puppet/parser/functions/defined.rb +2 -2
- data/lib/puppet/parser/functions/dig.rb +1 -1
- data/lib/puppet/parser/functions/each.rb +1 -1
- data/lib/puppet/parser/functions/epp.rb +2 -2
- data/lib/puppet/parser/functions/filter.rb +1 -1
- data/lib/puppet/parser/functions/find_file.rb +28 -0
- data/lib/puppet/parser/functions/hiera.rb +4 -4
- data/lib/puppet/parser/functions/hiera_array.rb +1 -1
- data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
- data/lib/puppet/parser/functions/hiera_include.rb +1 -1
- data/lib/puppet/parser/functions/include.rb +4 -8
- data/lib/puppet/parser/functions/inline_epp.rb +1 -1
- data/lib/puppet/parser/functions/lest.rb +1 -1
- data/lib/puppet/parser/functions/lookup.rb +4 -2
- data/lib/puppet/parser/functions/map.rb +1 -1
- data/lib/puppet/parser/functions/match.rb +1 -1
- data/lib/puppet/parser/functions/new.rb +414 -18
- data/lib/puppet/parser/functions/next.rb +38 -0
- data/lib/puppet/parser/functions/reduce.rb +1 -1
- data/lib/puppet/parser/functions/regsubst.rb +4 -2
- data/lib/puppet/parser/functions/require.rb +4 -27
- data/lib/puppet/parser/functions/return.rb +71 -0
- data/lib/puppet/parser/functions/reverse_each.rb +1 -1
- data/lib/puppet/parser/functions/scanf.rb +13 -8
- data/lib/puppet/parser/functions/slice.rb +1 -1
- data/lib/puppet/parser/functions/split.rb +1 -1
- data/lib/puppet/parser/functions/step.rb +1 -1
- data/lib/puppet/parser/functions/strftime.rb +185 -0
- data/lib/puppet/parser/functions/then.rb +1 -1
- data/lib/puppet/parser/functions/type.rb +1 -1
- data/lib/puppet/parser/functions/with.rb +3 -3
- data/lib/puppet/parser/resource.rb +8 -5
- data/lib/puppet/parser/scope.rb +1 -1
- data/lib/puppet/plugins/configuration.rb +8 -0
- data/lib/puppet/plugins/data_providers.rb +1 -0
- data/lib/puppet/plugins/data_providers/data_provider.rb +7 -28
- data/lib/puppet/plugins/data_providers/registry.rb +1 -0
- data/lib/puppet/pops.rb +4 -0
- data/lib/puppet/pops/evaluator/access_operator.rb +36 -5
- data/lib/puppet/pops/evaluator/closure.rb +81 -12
- data/lib/puppet/pops/evaluator/compare_operator.rb +24 -1
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +29 -5
- data/lib/puppet/pops/evaluator/json_strict_literal_evaluator.rb +1 -1
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +53 -62
- data/lib/puppet/pops/evaluator/runtime3_support.rb +15 -6
- data/lib/puppet/pops/functions/dispatch.rb +9 -2
- data/lib/puppet/pops/functions/dispatcher.rb +3 -1
- data/lib/puppet/pops/functions/function.rb +19 -2
- data/lib/puppet/pops/issues.rb +9 -0
- data/lib/puppet/pops/label_provider.rb +2 -2
- data/lib/puppet/pops/loader/loader.rb +17 -0
- data/lib/puppet/pops/loader/static_loader.rb +0 -41
- data/lib/puppet/pops/lookup.rb +12 -0
- data/lib/puppet/pops/lookup/context.rb +86 -0
- data/lib/puppet/pops/lookup/explainer.rb +46 -6
- data/lib/puppet/pops/lookup/invocation.rb +19 -0
- data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
- data/lib/puppet/pops/model/factory.rb +20 -8
- data/lib/puppet/pops/model/model_label_provider.rb +3 -0
- data/lib/puppet/pops/model/model_meta.rb +2 -0
- data/lib/puppet/pops/model/model_tree_dumper.rb +14 -0
- data/lib/puppet/pops/parser/egrammar.ra +11 -6
- data/lib/puppet/pops/parser/eparser.rb +1112 -1086
- data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
- data/lib/puppet/pops/pcore.rb +1 -0
- data/lib/puppet/pops/puppet_stack.rb +3 -3
- data/lib/puppet/pops/resource/param.rb +5 -1
- data/lib/puppet/pops/resource/resource_type_impl.rb +8 -4
- data/lib/puppet/pops/resource/resource_type_set.pcore +1 -0
- data/lib/puppet/pops/serialization/abstract_reader.rb +19 -2
- data/lib/puppet/pops/serialization/abstract_writer.rb +16 -3
- data/lib/puppet/pops/serialization/deserializer.rb +5 -1
- data/lib/puppet/pops/serialization/extension.rb +2 -0
- data/lib/puppet/pops/serialization/json.rb +76 -26
- data/lib/puppet/pops/serialization/serializer.rb +5 -1
- data/lib/puppet/pops/serialization/time_factory.rb +2 -1
- data/lib/puppet/pops/time/timespan.rb +718 -0
- data/lib/puppet/pops/time/timestamp.rb +148 -0
- data/lib/puppet/pops/types/p_binary_type.rb +220 -0
- data/lib/puppet/pops/types/p_object_type.rb +12 -6
- data/lib/puppet/pops/types/p_sensitive_type.rb +5 -1
- data/lib/puppet/pops/types/p_timespan_type.rb +141 -0
- data/lib/puppet/pops/types/p_timestamp_type.rb +69 -0
- data/lib/puppet/pops/types/string_converter.rb +62 -0
- data/lib/puppet/pops/types/type_asserter.rb +1 -1
- data/lib/puppet/pops/types/type_calculator.rb +17 -3
- data/lib/puppet/pops/types/type_factory.rb +35 -1
- data/lib/puppet/pops/types/type_formatter.rb +64 -11
- data/lib/puppet/pops/types/type_mismatch_describer.rb +110 -61
- data/lib/puppet/pops/types/type_parser.rb +18 -4
- data/lib/puppet/pops/types/types.rb +98 -63
- data/lib/puppet/pops/validation.rb +9 -1
- data/lib/puppet/pops/validation/checker4_0.rb +7 -0
- data/lib/puppet/property.rb +1 -1
- data/lib/puppet/provider.rb +3 -6
- data/lib/puppet/provider/mcx/mcxcontent.rb +1 -1
- data/lib/puppet/provider/mount/parsed.rb +18 -4
- data/lib/puppet/provider/nameservice/directoryservice.rb +15 -7
- data/lib/puppet/provider/package/gem.rb +6 -1
- data/lib/puppet/provider/package/pip.rb +0 -1
- data/lib/puppet/provider/package/pkg.rb +5 -1
- data/lib/puppet/provider/package/pkgng.rb +1 -1
- data/lib/puppet/provider/package/yum.rb +10 -0
- data/lib/puppet/provider/service/launchd.rb +1 -0
- data/lib/puppet/provider/user/directoryservice.rb +6 -6
- data/lib/puppet/provider/yumrepo/inifile.rb +1 -1
- data/lib/puppet/provider/zpool/zpool.rb +1 -1
- data/lib/puppet/resource.rb +54 -12
- data/lib/puppet/resource/capability_finder.rb +15 -9
- data/lib/puppet/resource/catalog.rb +25 -6
- data/lib/puppet/resource/type.rb +3 -1
- data/lib/puppet/settings.rb +1 -1
- data/lib/puppet/settings/environment_conf.rb +12 -4
- data/lib/puppet/syntax_checkers/base64.rb +41 -0
- data/lib/puppet/syntax_checkers/json.rb +0 -2
- data/lib/puppet/transaction.rb +6 -0
- data/lib/puppet/transaction/additional_resource_generator.rb +5 -0
- data/lib/puppet/transaction/report.rb +7 -2
- data/lib/puppet/type.rb +2 -1
- data/lib/puppet/type/file/checksum.rb +1 -0
- data/lib/puppet/type/file/content.rb +4 -4
- data/lib/puppet/type/mount.rb +44 -0
- data/lib/puppet/type/ssh_authorized_key.rb +1 -1
- data/lib/puppet/type/tidy.rb +3 -0
- data/lib/puppet/type/user.rb +12 -6
- data/lib/puppet/util/log.rb +25 -0
- data/lib/puppet/util/plist.rb +8 -3
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet_x.rb +7 -1
- data/spec/integration/application/apply_spec.rb +118 -0
- data/spec/integration/parser/compiler_spec.rb +28 -0
- data/spec/integration/parser/pcore_resource_spec.rb +40 -3
- data/spec/integration/provider/mount_spec.rb +2 -1
- data/spec/integration/util/windows/principal_spec.rb +2 -2
- data/spec/integration/util/windows/registry_spec.rb +4 -4
- data/spec/lib/puppet_spec/compiler.rb +5 -1
- data/spec/lib/puppet_spec/unindent.rb +5 -0
- data/spec/shared_contexts/types_setup.rb +6 -0
- data/spec/shared_examples/rhel_package_provider.rb +16 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/agent_spec.rb +11 -0
- data/spec/unit/application/lookup_spec.rb +94 -3
- data/spec/unit/capability_spec.rb +22 -0
- data/spec/unit/configurer_spec.rb +8 -0
- data/spec/unit/face/epp_face_spec.rb +22 -3
- data/spec/unit/functions/assert_type_spec.rb +3 -3
- data/spec/unit/functions/binary_file_spec.rb +46 -0
- data/spec/unit/functions/break_spec.rb +89 -0
- data/spec/unit/{parser/functions → functions}/contain_spec.rb +68 -3
- data/spec/unit/functions/find_file_spec.rb +69 -0
- data/spec/unit/functions/include_spec.rb +175 -0
- data/spec/unit/functions/logging_spec.rb +54 -0
- data/spec/unit/functions/lookup_spec.rb +3 -3
- data/spec/unit/functions/new_spec.rb +105 -5
- data/spec/unit/functions/next_spec.rb +93 -0
- data/spec/unit/functions/require_spec.rb +83 -0
- data/spec/unit/functions/return_spec.rb +105 -0
- data/spec/unit/{parser/functions → functions}/shared.rb +14 -11
- data/spec/unit/functions/strftime_spec.rb +152 -0
- data/spec/unit/functions4_spec.rb +22 -0
- data/spec/unit/indirector/face_spec.rb +10 -2
- data/spec/unit/network/http/error_spec.rb +1 -2
- data/spec/unit/network/http/handler_spec.rb +6 -5
- data/spec/unit/parser/functions/hiera_array_spec.rb +1 -1
- data/spec/unit/parser/functions/hiera_hash_spec.rb +1 -1
- data/spec/unit/parser/functions/hiera_include_spec.rb +1 -1
- data/spec/unit/parser/functions/hiera_spec.rb +1 -1
- data/spec/unit/parser/functions/lookup_spec.rb +1 -1
- data/spec/unit/parser/functions/regsubst_spec.rb +1 -1
- data/spec/unit/parser/functions/split_spec.rb +1 -1
- data/spec/unit/pops/evaluator/access_ops_spec.rb +81 -1
- data/spec/unit/pops/evaluator/arithmetic_ops_spec.rb +170 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +29 -4
- data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +112 -4
- data/spec/unit/pops/loaders/dependency_loader_spec.rb +12 -0
- data/spec/unit/pops/loaders/static_loader_spec.rb +0 -26
- data/spec/unit/pops/lookup/context_spec.rb +149 -0
- data/spec/unit/pops/parser/parse_functions_spec.rb +19 -0
- data/spec/unit/pops/parser/parse_lambda_spec.rb +19 -0
- data/spec/unit/pops/puppet_stack_spec.rb +1 -1
- data/spec/unit/pops/resource/resource_type_impl_spec.rb +74 -0
- data/spec/unit/pops/serialization/packer_spec.rb +34 -14
- data/spec/unit/pops/serialization/serialization_spec.rb +67 -5
- data/spec/unit/pops/time/timespan_spec.rb +121 -0
- data/spec/unit/pops/types/p_binary_type_spec.rb +243 -0
- data/spec/unit/pops/types/p_object_type_spec.rb +7 -7
- data/spec/unit/pops/types/p_sensitive_type_spec.rb +1 -1
- data/spec/unit/pops/types/p_timespan_type_spec.rb +273 -0
- data/spec/unit/pops/types/p_timestamp_type_spec.rb +311 -0
- data/spec/unit/pops/types/p_type_set_type_spec.rb +13 -13
- data/spec/unit/pops/types/ruby_generator_spec.rb +12 -12
- data/spec/unit/pops/types/string_converter_spec.rb +89 -0
- data/spec/unit/pops/types/type_asserter_spec.rb +3 -3
- data/spec/unit/pops/types/type_calculator_spec.rb +113 -5
- data/spec/unit/pops/types/type_formatter_spec.rb +40 -0
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +49 -38
- data/spec/unit/pops/types/type_parser_spec.rb +87 -4
- data/spec/unit/pops/types/types_spec.rb +1 -1
- data/spec/unit/pops/validator/validator_spec.rb +23 -0
- data/spec/unit/provider/mount/parsed_spec.rb +47 -29
- data/spec/unit/provider/package/pkg_spec.rb +109 -99
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +1 -0
- data/spec/unit/provider/user/aix_spec.rb +1 -1
- data/spec/unit/provider/user/directoryservice_spec.rb +101 -30
- data/spec/unit/resource/capability_finder_spec.rb +29 -7
- data/spec/unit/resource/catalog_spec.rb +127 -0
- data/spec/unit/ssl/certificate_request_spec.rb +1 -1
- data/spec/unit/transaction/additional_resource_generator_spec.rb +30 -0
- data/spec/unit/transaction/persistence_spec.rb +1 -6
- data/spec/unit/transaction/report_spec.rb +23 -0
- data/spec/unit/transaction_spec.rb +38 -0
- data/spec/unit/type/mount_spec.rb +5 -0
- data/spec/unit/util/plist_spec.rb +14 -2
- metadata +71 -12
- data/spec/integration/parser/functions/require_spec.rb +0 -43
- data/spec/unit/parser/functions/include_spec.rb +0 -55
- data/spec/unit/parser/functions/require_spec.rb +0 -68
@@ -0,0 +1,148 @@
|
|
1
|
+
module Puppet::Pops
|
2
|
+
module Time
|
3
|
+
class Timestamp < TimeData
|
4
|
+
DEFAULT_FORMATS_WO_TZ = ['%FT%T.L', '%FT%T', '%F']
|
5
|
+
DEFAULT_FORMATS = ['%FT%T.%L %Z', '%FT%T %Z', '%F %Z'] + DEFAULT_FORMATS_WO_TZ
|
6
|
+
|
7
|
+
CURRENT_TIMEZONE = 'current'.freeze
|
8
|
+
KEY_TIMEZONE = 'timezone'.freeze
|
9
|
+
|
10
|
+
# Converts a timezone that strptime can parse using '%z' into '-HH:MM' or '+HH:MM'
|
11
|
+
# @param [String] tz the timezone to convert
|
12
|
+
# @return [String] the converted timezone
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def self.convert_timezone(tz)
|
16
|
+
if tz =~ /\A[+-]\d\d:\d\d\z/
|
17
|
+
tz
|
18
|
+
else
|
19
|
+
offset = utc_offset(tz) / 60
|
20
|
+
if offset < 0
|
21
|
+
offset = offset.abs
|
22
|
+
sprintf('-%2.2d:%2.2d', offset / 60, offset % 60)
|
23
|
+
else
|
24
|
+
sprintf('+%2.2d:%2.2d', offset / 60, offset % 60)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the zone offset from utc for the given `timezone`
|
30
|
+
# @param [String] timezone the timezone to get the offset for
|
31
|
+
# @return [Integer] the timezone offset, in seconds
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
def self.utc_offset(timezone)
|
35
|
+
if CURRENT_TIMEZONE.casecmp(timezone) == 0
|
36
|
+
::Time.now.utc_offset
|
37
|
+
else
|
38
|
+
hash = DateTime._strptime(timezone, '%z')
|
39
|
+
offset = hash.nil? ? nil : hash[:offset]
|
40
|
+
raise ArgumentError, "Illegal timezone '#{timezone}'" if offset.nil?
|
41
|
+
offset
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Formats a ruby Time object using the given timezone
|
46
|
+
def self.format_time(format, time, timezone)
|
47
|
+
unless timezone.nil? || timezone.empty?
|
48
|
+
time = time.localtime(convert_timezone(timezone))
|
49
|
+
end
|
50
|
+
time.strftime(format)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.now
|
54
|
+
from_time(::Time.now)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.from_time(t)
|
58
|
+
new(t.tv_sec * NSECS_PER_SEC + t.tv_nsec)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.from_hash(args_hash)
|
62
|
+
parse(args_hash[KEY_STRING], args_hash[KEY_FORMAT], args_hash[KEY_TIMEZONE])
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.parse(str, format = :default, timezone = nil)
|
66
|
+
has_timezone = !(timezone.nil? || timezone.empty? || timezone == :default)
|
67
|
+
if format.nil? || format == :default
|
68
|
+
format = has_timezone ? DEFAULT_FORMATS_WO_TZ : DEFAULT_FORMATS
|
69
|
+
end
|
70
|
+
|
71
|
+
parsed = nil
|
72
|
+
if format.is_a?(Array)
|
73
|
+
format.each do |fmt|
|
74
|
+
assert_no_tz_extractor(fmt) if has_timezone
|
75
|
+
begin
|
76
|
+
parsed = DateTime.strptime(str, fmt)
|
77
|
+
break
|
78
|
+
rescue ArgumentError
|
79
|
+
end
|
80
|
+
end
|
81
|
+
raise ArgumentError, "Unable to parse '#{str}' using any of the formats #{format.join(', ')}" if parsed.nil?
|
82
|
+
else
|
83
|
+
assert_no_tz_extractor(format) if has_timezone
|
84
|
+
begin
|
85
|
+
parsed = DateTime.strptime(str, format)
|
86
|
+
rescue ArgumentError
|
87
|
+
raise ArgumentError, "Unable to parse '#{str}' using format '#{format}'"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
parsed_time = parsed.to_time
|
91
|
+
parsed_time -= utc_offset(timezone) if has_timezone
|
92
|
+
from_time(parsed_time)
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.assert_no_tz_extractor(format)
|
96
|
+
if format =~ /[^%]%[zZ]/
|
97
|
+
raise ArgumentError, 'Using a Timezone designator in format specification is mutually exclusive to providing an explicit timezone argument'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
undef_method :-@, :+@, :div, :fdiv, :abs, :abs2, :magnitude # does not make sense on a Timestamp
|
102
|
+
if method_defined?(:negative?)
|
103
|
+
undef_method :negative?, :positive?
|
104
|
+
end
|
105
|
+
if method_defined?(:%)
|
106
|
+
undef_method :%, :modulo, :divmod
|
107
|
+
end
|
108
|
+
|
109
|
+
def +(o)
|
110
|
+
case o
|
111
|
+
when Timespan
|
112
|
+
Timestamp.new(@nsecs + o.nsecs)
|
113
|
+
when Integer, Float
|
114
|
+
Timestamp.new(@nsecs + (o * NSECS_PER_SEC).to_i)
|
115
|
+
else
|
116
|
+
raise ArgumentError, "#{a_an_uc(o)} cannot be added to a Timestamp"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def -(o)
|
121
|
+
case o
|
122
|
+
when Timestamp
|
123
|
+
# Diff between two timestamps is a timespan
|
124
|
+
Timespan.new(@nsecs - o.nsecs)
|
125
|
+
when Timespan
|
126
|
+
Timestamp.new(@nsecs - o.nsecs)
|
127
|
+
when Integer, Float
|
128
|
+
# Subtract seconds
|
129
|
+
Timestamp.new(@nsecs - (o * NSECS_PER_SEC).to_i)
|
130
|
+
else
|
131
|
+
raise ArgumentError, "#{a_an_uc(o)} cannot be subtracted from a Timestamp"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def format(format, timezone = nil)
|
136
|
+
self.class.format_time(format, to_time, timezone)
|
137
|
+
end
|
138
|
+
|
139
|
+
def to_s
|
140
|
+
format(DEFAULT_FORMATS[0])
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_time
|
144
|
+
::Time.at(to_r).utc
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'base64'
|
2
|
+
module Puppet::Pops
|
3
|
+
module Types
|
4
|
+
|
5
|
+
# A Puppet Language Type that exposes the {{SemanticPuppet::Version}} and {{SemanticPuppet::VersionRange}}.
|
6
|
+
# The version type is parameterized with version ranges.
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
class PBinaryType < PAnyType
|
10
|
+
|
11
|
+
# Represents a binary buffer
|
12
|
+
# @api public
|
13
|
+
class Binary
|
14
|
+
attr_reader :binary_buffer
|
15
|
+
|
16
|
+
# Constructs an instance of Binary from a base64 urlsafe encoded string (RFC 2045).
|
17
|
+
# @param [String] A string with RFC 2045 compliant encoded binary
|
18
|
+
#
|
19
|
+
def self.from_base64(str)
|
20
|
+
new(Base64.decode64(str))
|
21
|
+
end
|
22
|
+
|
23
|
+
# Constructs an instance of Binary from a base64 encoded string (RFC4648 with "URL and Filename
|
24
|
+
# Safe Alphabet" (That is with '-' instead of '+', and '_' instead of '/').
|
25
|
+
#
|
26
|
+
def self.from_base64_urlsafe(str)
|
27
|
+
new(Base64.urlsafe_decode64(str))
|
28
|
+
end
|
29
|
+
|
30
|
+
# Constructs an instance of Binary from a base64 strict encoded string (RFC 4648)
|
31
|
+
# Where correct padding must be used and line breaks causes an error to be raised.
|
32
|
+
#
|
33
|
+
# @param [String] A string with RFC 4648 compliant encoded binary
|
34
|
+
#
|
35
|
+
def self.from_base64_strict(str)
|
36
|
+
new(Base64.strict_decode64(str))
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates a new Binary from a String containing binary data. If the string's encoding
|
40
|
+
# is not already ASCII-8BIT, a copy of the string is force encoded as ASCII-8BIT (that is Ruby's "binary" format).
|
41
|
+
# This means that this binary will have the exact same content, but the string will considered
|
42
|
+
# to hold a sequence of bytes in the range 0 to 255.
|
43
|
+
#
|
44
|
+
# The given string will be frozen as a side effect if it is in ASCII-8BIT encoding. If this is not
|
45
|
+
# wanted, a copy should be given to this method.
|
46
|
+
#
|
47
|
+
# @param [String] A string with binary data
|
48
|
+
# @api public
|
49
|
+
#
|
50
|
+
def self.from_binary_string(bin)
|
51
|
+
new(bin)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Creates a new Binary from a String containing text/binary in its given encoding. If the string's encoding
|
55
|
+
# is not already UTF-8, the string is first transcoded to UTF-8.
|
56
|
+
# This means that this binary will have the UTF-8 byte representation of the original string.
|
57
|
+
# For this to be valid, the encoding used in the given string must be valid.
|
58
|
+
# The validity of the given string is therefore asserted.
|
59
|
+
#
|
60
|
+
# The given string will be frozen as a side effect if it is in ASCII-8BIT encoding. If this is not
|
61
|
+
# wanted, a copy should be given to this method.
|
62
|
+
#
|
63
|
+
# @param [String] A string with valid content in its given encoding
|
64
|
+
# @return [Puppet::Pops::Types::PBinaryType::Binary] with the UTF-8 representation of the UTF-8 transcoded string
|
65
|
+
# @api public
|
66
|
+
#
|
67
|
+
def self.from_string(encoded_string)
|
68
|
+
enc = encoded_string.encoding.name
|
69
|
+
unless encoded_string.valid_encoding?
|
70
|
+
raise ArgumentError, "The given string in encoding '#{enc}' is invalid. Cannot create a Binary UTF-8 representation"
|
71
|
+
end
|
72
|
+
# Convert to UTF-8 (if not already UTF-8), and then to binary
|
73
|
+
encoded_string = (enc == "UTF-8") ? encoded_string.dup : encoded_string.encode('UTF-8')
|
74
|
+
encoded_string.force_encoding("ASCII-8BIT")
|
75
|
+
new(encoded_string)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Creates a new Binary from a String containing raw binary data of unknown encoding. If the string's encoding
|
79
|
+
# is not already ASCII-8BIT, a copy of the string is forced to ASCII-8BIT (that is Ruby's "binary" format).
|
80
|
+
# This means that this binary will have the exact same content, but the string will considered
|
81
|
+
# to hold a sequence of bytes in the range 0 to 255.
|
82
|
+
#
|
83
|
+
# @param [String] A string with binary data
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
def initialize(bin)
|
87
|
+
# TODO: When Ruby 1.9.3 support is dropped change this to `bin.b` for binary encoding instead of force_encoding
|
88
|
+
@binary_buffer = (bin.encoding.name == "ASCII-8BIT" ? bin : bin.dup.force_encoding("ASCII-8BIT")).freeze
|
89
|
+
end
|
90
|
+
|
91
|
+
# Presents the binary content as a string base64 encoded string (without line breaks).
|
92
|
+
#
|
93
|
+
def to_s
|
94
|
+
Base64.strict_encode64(@binary_buffer)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the binary content as a "relaxed" base64 (standard) encoding where
|
98
|
+
# the string is broken up with new lines.
|
99
|
+
def relaxed_to_s
|
100
|
+
Base64.encode64(@binary_buffer)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns the binary content as a url safe base64 string (where + and / are replaced by - and _)
|
104
|
+
#
|
105
|
+
def urlsafe_to_s
|
106
|
+
Base64.urlsafe_encode64(@binary_buffer)
|
107
|
+
end
|
108
|
+
|
109
|
+
def hash
|
110
|
+
@binary_buffer.hash
|
111
|
+
end
|
112
|
+
|
113
|
+
def eql?(o)
|
114
|
+
self.class == o.class && @binary_buffer == o.binary_buffer
|
115
|
+
end
|
116
|
+
|
117
|
+
def ==(o)
|
118
|
+
self.eql?(o)
|
119
|
+
end
|
120
|
+
|
121
|
+
def length()
|
122
|
+
@binary_buffer.length
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.register_ptype(loader, ir)
|
127
|
+
create_ptype(loader, ir, 'AnyType')
|
128
|
+
end
|
129
|
+
|
130
|
+
# Only instances of Binary are instances of the PBinaryType
|
131
|
+
#
|
132
|
+
def instance?(o, guard = nil)
|
133
|
+
o.is_a?(Binary)
|
134
|
+
end
|
135
|
+
|
136
|
+
def eql?(o)
|
137
|
+
self.class == o.class
|
138
|
+
end
|
139
|
+
|
140
|
+
# @api private
|
141
|
+
def self.new_function(_, loader)
|
142
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_Binary, loader) do
|
143
|
+
local_types do
|
144
|
+
type 'ByteInteger = Integer[0,255]'
|
145
|
+
type 'Base64Format = Enum["%b", "%u", "%B", "%s", "%r"]'
|
146
|
+
type 'StringHash = Struct[{value => String, "format" => Optional[Base64Format]}]'
|
147
|
+
type 'ArrayHash = Struct[{value => Array[ByteInteger]}]'
|
148
|
+
type 'BinaryArgsHash = Variant[StringHash, ArrayHash]'
|
149
|
+
end
|
150
|
+
|
151
|
+
# Creates a binary from a base64 encoded string in one of the formats %b, %u, %B, %s, or %r
|
152
|
+
dispatch :from_string do
|
153
|
+
param 'String', :str
|
154
|
+
optional_param 'Base64Format', :format
|
155
|
+
end
|
156
|
+
|
157
|
+
dispatch :from_array do
|
158
|
+
param 'Array[ByteInteger]', :byte_array
|
159
|
+
end
|
160
|
+
|
161
|
+
# Same as from_string, or from_array, but value and (for string) optional format are given in the form
|
162
|
+
# of a hash.
|
163
|
+
#
|
164
|
+
dispatch :from_hash do
|
165
|
+
param 'BinaryArgsHash', :hash_args
|
166
|
+
end
|
167
|
+
|
168
|
+
def from_string(str, format = nil)
|
169
|
+
format ||= '%B'
|
170
|
+
case format
|
171
|
+
when "%b"
|
172
|
+
# padding must be added for older rubies to avoid truncation
|
173
|
+
padding = '=' * (str.length % 3)
|
174
|
+
Binary.new(Base64.decode64(str + padding))
|
175
|
+
|
176
|
+
when "%u"
|
177
|
+
Binary.new(Base64.urlsafe_decode64(str))
|
178
|
+
|
179
|
+
when "%B"
|
180
|
+
Binary.new(Base64.strict_decode64(str))
|
181
|
+
|
182
|
+
when "%s"
|
183
|
+
Binary.from_string(str)
|
184
|
+
|
185
|
+
when "%r"
|
186
|
+
Binary.from_binary_string(str)
|
187
|
+
|
188
|
+
else
|
189
|
+
raise ArgumentError, "Unsupported Base64 format '#{format}'"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def from_array(array)
|
194
|
+
# The array is already known to have bytes in the range 0-255, or it is in error
|
195
|
+
# Without this pack C would produce weird results
|
196
|
+
Binary.from_binary_string(array.pack("C*"))
|
197
|
+
end
|
198
|
+
|
199
|
+
def from_hash(hash)
|
200
|
+
case hash['value']
|
201
|
+
when Array
|
202
|
+
from_array(hash['value'])
|
203
|
+
when String
|
204
|
+
from_string(hash['value'], hash['format'])
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
DEFAULT = PBinaryType.new
|
211
|
+
|
212
|
+
protected
|
213
|
+
|
214
|
+
def _assignable?(o, guard)
|
215
|
+
o.class == self.class
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -201,17 +201,23 @@ class PObjectType < PMetaType
|
|
201
201
|
@dispatch ||= create_dispatch(receiver)
|
202
202
|
|
203
203
|
args_type = TypeCalculator.infer_set(block_given? ? args + [block] : args)
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
@dispatch.invoke(receiver, scope, args, &block)
|
204
|
+
found = @dispatch.find { |d| d.type.callable?(args_type) }
|
205
|
+
raise ArgumentError, TypeMismatchDescriber.describe_signatures(label, @dispatch, args_type) if found.nil?
|
206
|
+
found.invoke(receiver, scope, args, &block)
|
208
207
|
end
|
209
208
|
|
210
209
|
# @api private
|
211
210
|
def create_dispatch(instance)
|
212
211
|
# TODO: Assumes Ruby implementation for now
|
213
|
-
|
214
|
-
callable_type.
|
212
|
+
if(callable_type.is_a?(PVariantType))
|
213
|
+
callable_type.types.map do |ct|
|
214
|
+
Functions::Dispatch.new(ct, name, [],
|
215
|
+
ct.block_type.nil? ? nil : 'block', nil, nil, false)
|
216
|
+
end
|
217
|
+
else
|
218
|
+
[Functions::Dispatch.new(callable_type, name, [],
|
219
|
+
callable_type.block_type.nil? ? nil : 'block', nil, nil, false)]
|
220
|
+
end
|
215
221
|
end
|
216
222
|
|
217
223
|
# @api private
|
@@ -6,7 +6,7 @@ module Types
|
|
6
6
|
#
|
7
7
|
#
|
8
8
|
# @api public
|
9
|
-
class PSensitiveType <
|
9
|
+
class PSensitiveType < PTypeWithContainedType
|
10
10
|
|
11
11
|
class Sensitive
|
12
12
|
def initialize(value)
|
@@ -26,6 +26,10 @@ class PSensitiveType < Puppet::Pops::Types::PTypeWithContainedType
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
def self.register_ptype(loader, ir)
|
30
|
+
create_ptype(loader, ir, 'AnyType')
|
31
|
+
end
|
32
|
+
|
29
33
|
def initialize(type = nil)
|
30
34
|
@type = type.nil? ? PAnyType.new : type.generalize
|
31
35
|
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Puppet::Pops
|
2
|
+
module Types
|
3
|
+
class PAbstractTimeDataType < PAbstractRangeType
|
4
|
+
# @param [AbstractTime] min lower bound for this type. Nil or :default means unbounded
|
5
|
+
# @param [AbstractTime] max upper bound for this type. Nil or :default means unbounded
|
6
|
+
def initialize(min = nil, max = nil)
|
7
|
+
super(convert_arg(min, true), convert_arg(max, false))
|
8
|
+
end
|
9
|
+
|
10
|
+
def convert_arg(arg, min)
|
11
|
+
case arg
|
12
|
+
when impl_class
|
13
|
+
arg
|
14
|
+
when Hash
|
15
|
+
impl_class.from_hash(arg)
|
16
|
+
when nil, :default
|
17
|
+
nil
|
18
|
+
when String
|
19
|
+
impl_class.parse(arg)
|
20
|
+
when Integer
|
21
|
+
arg == impl_class.new(arg * Time::NSECS_PER_SEC)
|
22
|
+
when Float
|
23
|
+
arg == (min ? -Float::INFINITY : Float::INFINITY) ? arg : impl_class.new(arg * Time::NSECS_PER_SEC)
|
24
|
+
else
|
25
|
+
raise ArgumentError, "Unable to create a #{impl_class.name} from a #{arg.class.name}" unless arg.nil? || arg == :default
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Concatenates this range with another range provided that the ranges intersect or
|
31
|
+
# are adjacent. When that's not the case, this method will return `nil`
|
32
|
+
#
|
33
|
+
# @param o [PAbstractTimeDataType] the range to concatenate with this range
|
34
|
+
# @return [PAbstractTimeDataType,nil] the concatenated range or `nil` when the ranges were apart
|
35
|
+
# @api public
|
36
|
+
def merge(o)
|
37
|
+
if intersect?(o) || adjacent?(o)
|
38
|
+
new_min = numeric_from <= o.numeric_from ? numeric_from : o.numeric_from
|
39
|
+
new_max = numeric_to >= o.numeric_to ? numeric_to : o.numeric_to
|
40
|
+
self.class.new(new_min, new_max)
|
41
|
+
else
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def _assignable?(o, guard)
|
47
|
+
self.class == o.class && numeric_from <= o.numeric_from && numeric_to >= o.numeric_to
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class PTimespanType < PAbstractTimeDataType
|
52
|
+
def self.register_ptype(loader, ir)
|
53
|
+
create_ptype(loader, ir, 'ScalarType',
|
54
|
+
'from' => { KEY_TYPE => PTimespanType::DEFAULT, KEY_VALUE => :default },
|
55
|
+
'to' => { KEY_TYPE => PTimespanType::DEFAULT, KEY_VALUE => :default }
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.new_function(_, loader)
|
60
|
+
@new_function ||= Puppet::Functions.create_loaded_function(:new_timespan, loader) do
|
61
|
+
local_types do
|
62
|
+
type 'Formats = Variant[String[2],Array[String[2]], 1]'
|
63
|
+
end
|
64
|
+
|
65
|
+
dispatch :from_seconds do
|
66
|
+
param 'Variant[Integer,Float]', :seconds
|
67
|
+
end
|
68
|
+
|
69
|
+
dispatch :from_string do
|
70
|
+
param 'String[1]', :string
|
71
|
+
optional_param 'Formats', :format
|
72
|
+
end
|
73
|
+
|
74
|
+
dispatch :from_fields do
|
75
|
+
param 'Integer', :days
|
76
|
+
param 'Integer', :hours
|
77
|
+
param 'Integer', :minutes
|
78
|
+
param 'Integer', :seconds
|
79
|
+
optional_param 'Integer', :milliseconds
|
80
|
+
optional_param 'Integer', :microseconds
|
81
|
+
optional_param 'Integer', :nanoseconds
|
82
|
+
end
|
83
|
+
|
84
|
+
dispatch :from_string_hash do
|
85
|
+
param <<-TYPE, :hash_arg
|
86
|
+
Struct[{
|
87
|
+
string => String[1],
|
88
|
+
Optional[format] => Formats
|
89
|
+
}]
|
90
|
+
TYPE
|
91
|
+
end
|
92
|
+
|
93
|
+
dispatch :from_fields_hash do
|
94
|
+
param <<-TYPE, :hash_arg
|
95
|
+
Struct[{
|
96
|
+
Optional[negative] => Boolean,
|
97
|
+
Optional[days] => Integer,
|
98
|
+
Optional[hours] => Integer,
|
99
|
+
Optional[minutes] => Integer,
|
100
|
+
Optional[seconds] => Integer,
|
101
|
+
Optional[milliseconds] => Integer,
|
102
|
+
Optional[microseconds] => Integer,
|
103
|
+
Optional[nanoseconds] => Integer
|
104
|
+
}]
|
105
|
+
TYPE
|
106
|
+
end
|
107
|
+
|
108
|
+
def from_seconds(seconds)
|
109
|
+
Time::Timespan.new((seconds * Time::NSECS_PER_SEC).to_i)
|
110
|
+
end
|
111
|
+
|
112
|
+
def from_string(string, format = Time::Timespan::Format::DEFAULTS)
|
113
|
+
Time::Timespan.parse(string, format)
|
114
|
+
end
|
115
|
+
|
116
|
+
def from_fields(days, hours, minutes, seconds, milliseconds = 0, microseconds = 0, nanoseconds = 0)
|
117
|
+
Time::Timespan.from_fields(days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds)
|
118
|
+
end
|
119
|
+
|
120
|
+
def from_string_hash(args_hash)
|
121
|
+
Time::Timespan.from_string_hash(args_hash)
|
122
|
+
end
|
123
|
+
|
124
|
+
def from_fields_hash(args_hash)
|
125
|
+
Time::Timespan.from_fields_hash(args_hash)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def generalize
|
131
|
+
DEFAULT
|
132
|
+
end
|
133
|
+
|
134
|
+
def impl_class
|
135
|
+
Time::Timespan
|
136
|
+
end
|
137
|
+
|
138
|
+
DEFAULT = PTimespanType.new(nil, nil)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|