bolt 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/bolt/cli.rb +43 -43
- data/lib/bolt/config.rb +25 -5
- data/lib/bolt/node.rb +3 -1
- data/lib/bolt/node/ssh.rb +15 -2
- data/lib/bolt/node/winrm.rb +20 -9
- data/lib/bolt/version.rb +1 -1
- data/modules/boltlib/lib/puppet/functions/run_plan.rb +1 -1
- data/modules/boltlib/lib/puppet/functions/run_task.rb +29 -32
- data/vendored/puppet/lib/puppet.rb +2 -5
- data/vendored/puppet/lib/puppet/application.rb +18 -1
- data/vendored/puppet/lib/puppet/application/agent.rb +8 -1
- data/vendored/puppet/lib/puppet/application/config.rb +1 -0
- data/vendored/puppet/lib/puppet/application/device.rb +1 -2
- data/vendored/puppet/lib/puppet/application/filebucket.rb +10 -2
- data/vendored/puppet/lib/puppet/application/help.rb +1 -0
- data/vendored/puppet/lib/puppet/application_support.rb +6 -1
- data/vendored/puppet/lib/puppet/configurer.rb +8 -3
- data/vendored/puppet/lib/puppet/defaults.rb +29 -9
- data/vendored/puppet/lib/puppet/environments.rb +2 -0
- data/vendored/puppet/lib/puppet/face/config.rb +14 -1
- data/vendored/puppet/lib/puppet/face/module/list.rb +1 -1
- data/vendored/puppet/lib/puppet/face/module/search.rb +4 -1
- data/vendored/puppet/lib/puppet/forge.rb +6 -0
- data/vendored/puppet/lib/puppet/functions/convert_to.rb +32 -0
- data/vendored/puppet/lib/puppet/gettext/config.rb +135 -37
- data/vendored/puppet/lib/puppet/gettext/module_translations.rb +42 -0
- data/vendored/puppet/lib/puppet/indirector/catalog/compiler.rb +2 -0
- data/vendored/puppet/lib/puppet/module.rb +10 -18
- data/vendored/puppet/lib/puppet/network/http/factory.rb +9 -0
- data/vendored/puppet/lib/puppet/node/environment.rb +14 -0
- data/vendored/puppet/lib/puppet/parser/functions/sprintf.rb +17 -3
- data/vendored/puppet/lib/puppet/parser/scope.rb +11 -0
- data/vendored/puppet/lib/puppet/pops.rb +0 -1
- data/vendored/puppet/lib/puppet/pops/evaluator/epp_evaluator.rb +13 -0
- data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +39 -5
- data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +64 -24
- data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +1 -1
- data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +21 -70
- data/vendored/puppet/lib/puppet/pops/lookup/hiera_config.rb +2 -2
- data/vendored/puppet/lib/puppet/pops/parser/parser_support.rb +1 -1
- data/vendored/puppet/lib/puppet/pops/pcore.rb +43 -1
- data/vendored/puppet/lib/puppet/pops/types/type_factory.rb +4 -0
- data/vendored/puppet/lib/puppet/pops/types/types.rb +25 -5
- data/vendored/puppet/lib/puppet/provider/selmodule/semodule.rb +5 -3
- data/vendored/puppet/lib/puppet/provider/service/smf.rb +2 -0
- data/vendored/puppet/lib/puppet/settings/environment_conf.rb +14 -2
- data/vendored/puppet/lib/puppet/ssl/certificate_authority.rb +1 -1
- data/vendored/puppet/lib/puppet/ssl/certificate_signer.rb +6 -0
- data/vendored/puppet/lib/puppet/ssl/host.rb +1 -1
- data/vendored/puppet/lib/puppet/type/file/checksum.rb +1 -1
- data/vendored/puppet/lib/puppet/type/file/checksum_value.rb +4 -3
- data/vendored/puppet/lib/puppet/type/k5login.rb +101 -0
- data/vendored/puppet/lib/puppet/type/tidy.rb +4 -2
- data/vendored/puppet/lib/puppet/util/checksums.rb +82 -1
- data/vendored/puppet/lib/puppet/util/command_line.rb +5 -0
- data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +5 -1
- data/vendored/puppet/lib/puppet_pal.rb +272 -11
- data/vendored/require_vendored.rb +0 -6
- metadata +8 -8
- data/vendored/puppet/lib/puppet/bindings.rb +0 -147
- data/vendored/puppet/lib/puppet/pops/types/task.rb +0 -116
@@ -4,7 +4,6 @@ module Puppet::Pops
|
|
4
4
|
module Loader
|
5
5
|
class TaskInstantiator
|
6
6
|
def self.create(loader, typed_name, source_refs)
|
7
|
-
ensure_initialized
|
8
7
|
name = typed_name.name
|
9
8
|
metadata = nil
|
10
9
|
task_source = nil
|
@@ -23,95 +22,47 @@ class TaskInstantiator
|
|
23
22
|
raise ArgumentError, _('No source besides task metadata was found in directory %{directory} for task %{name}') %
|
24
23
|
{ name: name, directory: File.dirname(source_refs[0]) }
|
25
24
|
end
|
26
|
-
|
25
|
+
create_task(loader, name, task_source, metadata)
|
27
26
|
end
|
28
27
|
|
29
|
-
def self.
|
28
|
+
def self.create_task(loader, name, task_source, metadata)
|
30
29
|
if metadata.nil?
|
31
|
-
|
30
|
+
create_task_from_hash(loader, name, task_source, EMPTY_HASH)
|
32
31
|
else
|
33
32
|
json_text = loader.get_contents(metadata)
|
34
33
|
begin
|
35
|
-
|
36
|
-
Types::TypeAsserter.assert_instance_of(nil, @type_hash_t, hash) { _('The metadata for task %{name}') % { name: typed_name.name } }
|
37
|
-
create_task_type_from_hash(loader, typed_name, task_source, hash)
|
34
|
+
create_task_from_hash(loader, name, task_source, JSON.parse(json_text) || EMPTY_HASH)
|
38
35
|
rescue JSON::ParserError => ex
|
39
36
|
raise Puppet::ParseError.new(ex.message, metadata)
|
40
37
|
rescue Types::TypeAssertionError => ex
|
41
38
|
# Not strictly a parser error but from the users perspective, the file content didn't parse properly. The
|
42
39
|
# ParserError also conveys file info (even though line is unknown)
|
43
|
-
|
40
|
+
msg = _('Failed to load metadata for task %{name}: %{reason}') % { :name => name, :reason => ex.message }
|
41
|
+
raise Puppet::ParseError.new(msg, metadata)
|
44
42
|
end
|
45
43
|
end
|
46
44
|
end
|
47
45
|
|
48
|
-
def self.
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
params_t = tf.hash_kv(
|
54
|
-
Types::Task::PARAMETER_NAME_PATTERN,
|
55
|
-
tf.struct(
|
56
|
-
tf.optional('description') => tf.string,
|
57
|
-
tf.optional('type') => Types::PStringType::NON_EMPTY,
|
58
|
-
tf.optional('sensitive') => tf.boolean
|
59
|
-
)
|
60
|
-
)
|
61
|
-
|
62
|
-
@type_hash_t = tf.struct(
|
63
|
-
tf.optional('description') => tf.string,
|
64
|
-
tf.optional('puppet_task_version') => tf.integer,
|
65
|
-
tf.optional('supports_noop') => tf.boolean,
|
66
|
-
tf.optional('input_method') => tf.enum('stdin', 'environment'),
|
67
|
-
'parameters' => params_t,
|
68
|
-
tf.optional('output') => params_t
|
69
|
-
)
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.create_task_type_from_hash(loader, typed_name, task_source, hash)
|
73
|
-
attributes = {}
|
74
|
-
constants = {}
|
75
|
-
parameters_entry_found = false
|
46
|
+
def self.create_task_from_hash(loader, name, task_source, hash)
|
47
|
+
arguments = {
|
48
|
+
'name' => name,
|
49
|
+
'executable' => task_source
|
50
|
+
}
|
76
51
|
hash.each_pair do |key, value|
|
77
|
-
if 'parameters' == key
|
78
|
-
|
79
|
-
value.each_pair do |
|
80
|
-
|
52
|
+
if 'parameters' == key || 'output' == key
|
53
|
+
ps = {}
|
54
|
+
value.each_pair do |k, v|
|
55
|
+
pd = v.dup
|
56
|
+
t = v['type']
|
57
|
+
pd['type'] = t.nil? ? Types::TypeFactory.data : Types::TypeParser.singleton.parse(t, loader)
|
58
|
+
ps[k] = pd
|
81
59
|
end
|
82
|
-
|
83
|
-
constants[key] = value
|
60
|
+
value = ps
|
84
61
|
end
|
62
|
+
arguments[key] = value
|
85
63
|
end
|
86
64
|
|
87
|
-
|
88
|
-
parent_type = 'Task'
|
89
|
-
else
|
90
|
-
# No entry means any parameters
|
91
|
-
attributes = EMPTY_HASH
|
92
|
-
parent_type = 'GenericTask'
|
93
|
-
end
|
94
|
-
|
95
|
-
constants['executable'] = Pathname(task_source).relative_path_from(Pathname(loader.path) + 'tasks').to_s
|
96
|
-
|
97
|
-
Types::TypeFactory.object(
|
98
|
-
{
|
99
|
-
'name' => Types::TypeFormatter.singleton.capitalize_segments(typed_name.name),
|
100
|
-
'parent' => Types::TypeParser.singleton.parse(parent_type, loader),
|
101
|
-
'attributes' => attributes,
|
102
|
-
'constants' => constants
|
103
|
-
}, loader)
|
104
|
-
end
|
105
|
-
|
106
|
-
def self.create_attribute(loader, param_decl)
|
107
|
-
result = {}
|
108
|
-
type = Types::TypeParser.singleton.parse(param_decl['type'] || 'Data', loader)
|
109
|
-
|
110
|
-
# Treat OptionalType as optional attribute entry, i.e. provide a default of undef
|
111
|
-
result['value'] = nil if type.is_a?(Types::POptionalType)
|
112
|
-
|
113
|
-
result['type'] = type
|
114
|
-
result
|
65
|
+
Types::TypeFactory.task.from_hash(arguments)
|
115
66
|
end
|
116
67
|
end
|
117
68
|
end
|
@@ -543,8 +543,8 @@ class HieraConfigV5 < HieraConfig
|
|
543
543
|
tf = Types::TypeFactory
|
544
544
|
nes_t = Types::PStringType::NON_EMPTY
|
545
545
|
|
546
|
-
#
|
547
|
-
uri_t =
|
546
|
+
# Validated using Ruby URI implementation
|
547
|
+
uri_t = Types::PStringType::NON_EMPTY
|
548
548
|
|
549
549
|
# The option name must start with a letter and end with a letter or digit. May contain underscore and dash.
|
550
550
|
option_name_t = tf.pattern(/\A[A-Za-z](:?[0-9A-Za-z_-]*[0-9A-Za-z])?\z/)
|
@@ -40,7 +40,6 @@ module Pcore
|
|
40
40
|
add_alias('Pcore::QRef', TYPE_QUALIFIED_REFERENCE, loader)
|
41
41
|
|
42
42
|
if Puppet[:tasks]
|
43
|
-
require_relative 'types/task'
|
44
43
|
require_relative 'types/execution_result'
|
45
44
|
|
46
45
|
add_object_type('Target', <<-PUPPET, loader)
|
@@ -51,6 +50,49 @@ module Pcore
|
|
51
50
|
}
|
52
51
|
}
|
53
52
|
PUPPET
|
53
|
+
|
54
|
+
add_object_type('Task', <<-PUPPET, loader)
|
55
|
+
{
|
56
|
+
attributes => {
|
57
|
+
# Fully qualified name of the task
|
58
|
+
name => { type => Pattern[/\\A[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)*\\z/] },
|
59
|
+
|
60
|
+
# Full path to executable
|
61
|
+
executable => { type => String },
|
62
|
+
|
63
|
+
# Task description
|
64
|
+
description => { type => Optional[String], value => undef },
|
65
|
+
|
66
|
+
# Puppet Task version
|
67
|
+
puppet_task_version => { type => Integer, value => 1 },
|
68
|
+
|
69
|
+
# Type, description, and sensitive property of each parameter
|
70
|
+
parameters => {
|
71
|
+
type => Optional[Hash[
|
72
|
+
Pattern[/\\A[a-z][a-z0-9_]*\\z/],
|
73
|
+
Struct[
|
74
|
+
Optional[description] => String,
|
75
|
+
Optional[sensitive] => Boolean,
|
76
|
+
type => Type[Optional[Data]]]]],
|
77
|
+
value => undef
|
78
|
+
},
|
79
|
+
|
80
|
+
# Type, description, and sensitive property of each output
|
81
|
+
output => {
|
82
|
+
type => Optional[Hash[
|
83
|
+
Pattern[/\\A[a-z][a-z0-9_]*\\z/],
|
84
|
+
Struct[
|
85
|
+
Optional[description] => String,
|
86
|
+
Optional[sensitive] => Boolean,
|
87
|
+
type => Type[Optional[Data]]]]],
|
88
|
+
value => undef
|
89
|
+
},
|
90
|
+
|
91
|
+
supports_noop => { type => Boolean, value => false },
|
92
|
+
input_method => { type => String, value => 'both' },
|
93
|
+
}
|
94
|
+
}
|
95
|
+
PUPPET
|
54
96
|
end
|
55
97
|
Types::TypedModelObject.register_ptypes(loader, ir)
|
56
98
|
|
@@ -60,8 +60,6 @@ class TypedModelObject < Object
|
|
60
60
|
RubyMethod.register_ptype(loader, ir),
|
61
61
|
]
|
62
62
|
if Puppet[:tasks]
|
63
|
-
types << Task.register_ptype(loader, ir)
|
64
|
-
types << GenericTask.register_ptype(loader, ir)
|
65
63
|
types << ExecutionResult.register_ptype(loader, ir)
|
66
64
|
end
|
67
65
|
|
@@ -135,8 +133,11 @@ class PAnyType < TypedModelObject
|
|
135
133
|
assignable?(o.resolved_type, guard)
|
136
134
|
end
|
137
135
|
when PVariantType
|
138
|
-
# Assignable if all contained types are assignable
|
139
|
-
|
136
|
+
# Assignable if all contained types are assignable, or if this is exactly Any
|
137
|
+
return true if self.class == PAnyType
|
138
|
+
# An empty variant may be assignable to NotUndef[T] if T is assignable to empty variant
|
139
|
+
return _assignable?(o, guard) if is_a?(PNotUndefType) && o.types.empty?
|
140
|
+
!o.types.empty? && o.types.all? { |vt| assignable?(vt, guard) }
|
140
141
|
when POptionalType
|
141
142
|
# Assignable if undef and contained type is assignable
|
142
143
|
assignable?(PUndefType::DEFAULT) && (o.type.nil? || assignable?(o.type))
|
@@ -655,7 +656,12 @@ class PUnitType < PAnyType
|
|
655
656
|
|
656
657
|
DEFAULT = PUnitType.new
|
657
658
|
|
659
|
+
def assignable?(o, guard=nil)
|
660
|
+
true
|
661
|
+
end
|
662
|
+
|
658
663
|
protected
|
664
|
+
|
659
665
|
# @api private
|
660
666
|
def _assignable?(o, guard)
|
661
667
|
true
|
@@ -2443,7 +2449,7 @@ class PCallableType < PAnyType
|
|
2443
2449
|
|
2444
2450
|
# @api private
|
2445
2451
|
def callable_args?(required_callable_t, guard)
|
2446
|
-
# If the required callable is
|
2452
|
+
# If the required callable is equal or more specific than self, self is acceptable arguments
|
2447
2453
|
required_callable_t.assignable?(self, guard)
|
2448
2454
|
end
|
2449
2455
|
|
@@ -3020,6 +3026,20 @@ class PVariantType < PAnyType
|
|
3020
3026
|
|
3021
3027
|
DEFAULT = PVariantType.new(EMPTY_ARRAY)
|
3022
3028
|
|
3029
|
+
def assignable?(o, guard = nil)
|
3030
|
+
# an empty Variant does not match Undef (it is void - not even undef)
|
3031
|
+
if o.is_a?(PUndefType) && types.empty?
|
3032
|
+
return false
|
3033
|
+
end
|
3034
|
+
|
3035
|
+
return super unless o.is_a?(PVariantType)
|
3036
|
+
# If empty, all Variant types match irrespective of the types they hold (including being empty)
|
3037
|
+
return true if types.empty?
|
3038
|
+
# Since this variant is not empty, an empty Variant cannot match, because it matches nothing
|
3039
|
+
# otherwise all types in o must be assignable to this
|
3040
|
+
!o.types.empty? && o.types.all? { |vt| super(vt, guard) }
|
3041
|
+
end
|
3042
|
+
|
3023
3043
|
protected
|
3024
3044
|
|
3025
3045
|
# @api private
|
@@ -118,11 +118,13 @@ Puppet::Type.type(:selmodule).provide(:semodule) do
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def selmodversion_loaded
|
121
|
-
|
121
|
+
selmod_output = []
|
122
|
+
selmodule_cmd = "#{command(:semodule)} --list"
|
122
123
|
begin
|
123
|
-
execpipe(
|
124
|
+
execpipe(selmodule_cmd) do |output|
|
124
125
|
output.each_line do |line|
|
125
126
|
line.chomp!
|
127
|
+
selmod_output << line
|
126
128
|
bits = line.split
|
127
129
|
if bits[0] == @resource[:name]
|
128
130
|
self.debug "load version #{bits[1]}"
|
@@ -131,7 +133,7 @@ Puppet::Type.type(:selmodule).provide(:semodule) do
|
|
131
133
|
end
|
132
134
|
end
|
133
135
|
rescue Puppet::ExecutionFailure
|
134
|
-
raise Puppet::ExecutionFailure, "Could not list policy modules:
|
136
|
+
raise Puppet::ExecutionFailure, _("Could not list policy modules: \"%{selmodule_command}\" failed with \"%{selmod_output}\"") % { selmodule_command: selmodule_cmd, selmod_output: selmod_output.join(' ') }
|
135
137
|
end
|
136
138
|
nil
|
137
139
|
end
|
@@ -107,6 +107,8 @@ Puppet::Type.type(:service).provide :smf, :parent => :base do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def stop
|
110
|
+
# Don't try to stop non-existing services (PUP-8167)
|
111
|
+
return if self.status == :absent
|
110
112
|
# Wait for the service to actually stop before returning.
|
111
113
|
super
|
112
114
|
self.wait('offline', 'disabled', 'uninitialized')
|
@@ -138,13 +138,25 @@ class Puppet::Settings::EnvironmentConf
|
|
138
138
|
section_keys = config.sections.keys
|
139
139
|
main = config.sections[:main]
|
140
140
|
if section_keys.size > 1
|
141
|
-
|
141
|
+
# warn once per config file path
|
142
|
+
Puppet.warn_once(
|
143
|
+
:invalid_settings_section, "EnvironmentConf-section:#{path_to_conf_file}",
|
144
|
+
_("Invalid sections in environment.conf at '%{path_to_conf_file}'. Environment conf may not have sections. The following sections are being ignored: '%{sections}'") % {
|
145
|
+
path_to_conf_file: path_to_conf_file,
|
146
|
+
sections: (section_keys - [:main]).join(',')
|
147
|
+
})
|
142
148
|
valid = false
|
143
149
|
end
|
144
150
|
|
145
151
|
extraneous_settings = main.settings.map(&:name) - VALID_SETTINGS
|
146
152
|
if !extraneous_settings.empty?
|
147
|
-
|
153
|
+
# warn once per config file path
|
154
|
+
Puppet.warn_once(
|
155
|
+
:invalid_settings, "EnvironmentConf-settings:#{path_to_conf_file}",
|
156
|
+
_("Invalid settings in environment.conf at '%{path_to_conf_file}'. The following unknown setting(s) are being ignored: %{ignored_settings}") % {
|
157
|
+
path_to_conf_file: path_to_conf_file,
|
158
|
+
ignored_settings: extraneous_settings.join(', ')
|
159
|
+
})
|
148
160
|
valid = false
|
149
161
|
end
|
150
162
|
|
@@ -399,7 +399,7 @@ class Puppet::SSL::CertificateAuthority
|
|
399
399
|
|
400
400
|
# Check for wildcards in the subjectAltName fields too.
|
401
401
|
if csr.subject_alt_names.any? {|x| x.include? '*' }
|
402
|
-
raise CertificateSigningError.new(hostname), _("CSR '%{csr}' subjectAltName contains a wildcard, which is not allowed: %{alt_names} To continue, this CSR needs to be cleaned.") % { csr: csr.name, alt_names: csr.subject_alt_names.join(', ') }
|
402
|
+
raise CertificateSigningError.new(hostname), _("CSR '%{csr}' subjectAltName contains a wildcard, which is not allowed: %{alt_names}. To continue, this CSR needs to be cleaned.") % { csr: csr.name, alt_names: csr.subject_alt_names.join(', ') }
|
403
403
|
end
|
404
404
|
end
|
405
405
|
|
@@ -14,6 +14,12 @@ class Puppet::SSL::CertificateSigner
|
|
14
14
|
@digest = OpenSSL::Digest::SHA256
|
15
15
|
elsif OpenSSL::Digest.const_defined?('SHA1')
|
16
16
|
@digest = OpenSSL::Digest::SHA1
|
17
|
+
elsif OpenSSL::Digest.const_defined?('SHA512')
|
18
|
+
@digest = OpenSSL::Digest::SHA512
|
19
|
+
elsif OpenSSL::Digest.const_defined?('SHA384')
|
20
|
+
@digest = OpenSSL::Digest::SHA384
|
21
|
+
elsif OpenSSL::Digest.const_defined?('SHA224')
|
22
|
+
@digest = OpenSSL::Digest::SHA224
|
17
23
|
else
|
18
24
|
raise Puppet::Error,
|
19
25
|
"No FIPS 140-2 compliant digest algorithm in OpenSSL::Digest"
|
@@ -320,7 +320,7 @@ ERROR_STRING
|
|
320
320
|
# configurable
|
321
321
|
# --jeffweiss 29 aug 2012
|
322
322
|
def suitable_message_digest_algorithms
|
323
|
-
[:SHA1, :SHA256, :SHA512]
|
323
|
+
[:SHA1, :SHA224, :SHA256, :SHA384, :SHA512]
|
324
324
|
end
|
325
325
|
|
326
326
|
# Attempt to retrieve a cert, if we don't already have one.
|
@@ -9,7 +9,7 @@ Puppet::Type.type(:file).newparam(:checksum) do
|
|
9
9
|
|
10
10
|
The default checksum type is md5."
|
11
11
|
|
12
|
-
newvalues "md5", "md5lite", "sha256", "sha256lite", "mtime", "ctime", "none"
|
12
|
+
newvalues "md5", "md5lite", "sha224", "sha256", "sha256lite", "sha384", "sha512", "mtime", "ctime", "none"
|
13
13
|
|
14
14
|
defaultto do
|
15
15
|
Puppet[:digest_algorithm].to_sym
|
@@ -6,9 +6,10 @@ module Puppet
|
|
6
6
|
include Puppet::Util::Checksums
|
7
7
|
include Puppet::DataSync
|
8
8
|
|
9
|
-
desc "The checksum of the source contents. Only md5
|
10
|
-
specifying this parameter. If this parameter is set,
|
11
|
-
assumed to be false, and ownership and permissions
|
9
|
+
desc "The checksum of the source contents. Only md5, sha256, sha224, sha384 and sha512
|
10
|
+
are supported when specifying this parameter. If this parameter is set,
|
11
|
+
source_permissions will be assumed to be false, and ownership and permissions
|
12
|
+
will not be read from source."
|
12
13
|
|
13
14
|
def insync?(is)
|
14
15
|
# If checksum_value and source are specified, manage the file contents.
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# Plug-in type for handling k5login files
|
2
2
|
require 'puppet/util'
|
3
|
+
require 'puppet/util/selinux'
|
3
4
|
|
4
5
|
Puppet::Type.newtype(:k5login) do
|
5
6
|
@doc = "Manage the `.k5login` file for a user. Specify the full path to
|
@@ -31,10 +32,60 @@ Puppet::Type.newtype(:k5login) do
|
|
31
32
|
defaultto { "644" }
|
32
33
|
end
|
33
34
|
|
35
|
+
# To manage the selinux user of the file
|
36
|
+
newproperty(:seluser) do
|
37
|
+
desc "What the SELinux user component of the context of the file should be.
|
38
|
+
Any valid SELinux user component is accepted. For example `user_u`.
|
39
|
+
If not specified it defaults to the value returned by matchpathcon for
|
40
|
+
the file, if any exists. Only valid on systems with SELinux support
|
41
|
+
enabled."
|
42
|
+
|
43
|
+
defaultto { "user_u" }
|
44
|
+
end
|
45
|
+
|
46
|
+
# To manage the selinux role of the file
|
47
|
+
newproperty(:selrole) do
|
48
|
+
desc "What the SELinux role component of the context of the file should be.
|
49
|
+
Any valid SELinux role component is accepted. For example `role_r`.
|
50
|
+
If not specified it defaults to the value returned by matchpathcon for
|
51
|
+
the file, if any exists. Only valid on systems with SELinux support
|
52
|
+
enabled."
|
53
|
+
|
54
|
+
defaultto { "object_r" }
|
55
|
+
end
|
56
|
+
|
57
|
+
# To manage the selinux type of the file
|
58
|
+
newproperty(:seltype) do
|
59
|
+
desc "What the SELinux type component of the context of the file should be.
|
60
|
+
Any valid SELinux type component is accepted. For example `tmp_t`.
|
61
|
+
If not specified it defaults to the value returned by matchpathcon for
|
62
|
+
the file, if any exists. Only valid on systems with SELinux support
|
63
|
+
enabled."
|
64
|
+
|
65
|
+
# to my knowledge, `krb5_home_t` is the only valid type for .k5login
|
66
|
+
defaultto { "krb5_home_t" }
|
67
|
+
end
|
68
|
+
|
69
|
+
# To manage the selinux range of the file
|
70
|
+
newproperty(:selrange) do
|
71
|
+
desc "What the SELinux range component of the context of the file should be.
|
72
|
+
Any valid SELinux range component is accepted. For example `s0` or
|
73
|
+
`SystemHigh`. If not specified it defaults to the value returned by
|
74
|
+
matchpathcon for the file, if any exists. Only valid on systems with
|
75
|
+
SELinux support enabled and that have support for MCS (Multi-Category
|
76
|
+
Security)."
|
77
|
+
|
78
|
+
defaultto { "s0" }
|
79
|
+
end
|
80
|
+
|
81
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
82
|
+
|
34
83
|
provide(:k5login) do
|
35
84
|
desc "The k5login provider is the only provider for the k5login
|
36
85
|
type."
|
37
86
|
|
87
|
+
include Puppet::Util::SELinux
|
88
|
+
|
38
89
|
# Does this file exist?
|
39
90
|
def exists?
|
40
91
|
Puppet::FileSystem.exist?(@resource[:name])
|
@@ -78,6 +129,56 @@ Puppet::Type.newtype(:k5login) do
|
|
78
129
|
File.chmod(Integer("0#{value}"), @resource[:name])
|
79
130
|
end
|
80
131
|
|
132
|
+
# Set the file seluser
|
133
|
+
def seluser
|
134
|
+
if selinux_support?
|
135
|
+
context = get_selinux_current_context(@resource[:name])
|
136
|
+
return parse_selinux_context(:seluser, context)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def seluser=(value)
|
141
|
+
set_selinux_context(@resource[:name], value, :seluser)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Set the file selrole
|
145
|
+
def selrole
|
146
|
+
if selinux_support?
|
147
|
+
context = get_selinux_current_context(@resource[:name])
|
148
|
+
return parse_selinux_context(:selrole, context)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Set the file seltype
|
153
|
+
def selrole=(value)
|
154
|
+
set_selinux_context(@resource[:name], value, :selrole)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Set the file seltype
|
158
|
+
def seltype
|
159
|
+
if selinux_support?
|
160
|
+
context = get_selinux_current_context(@resource[:name])
|
161
|
+
return parse_selinux_context(:seltype, context)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Set the file selrange
|
166
|
+
def seltype=(value)
|
167
|
+
set_selinux_context(@resource[:name], value, :seltype)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Set the file selrange
|
171
|
+
def selrange
|
172
|
+
if selinux_support?
|
173
|
+
context = get_selinux_current_context(@resource[:name])
|
174
|
+
return parse_selinux_context(:selrange, context)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def selrange=(value)
|
179
|
+
set_selinux_context(@resource[:name], value, :selrange)
|
180
|
+
end
|
181
|
+
|
81
182
|
private
|
82
183
|
def write(value)
|
83
184
|
Puppet::Util.replace_file(@resource[:name], 0644) do |f|
|