puppet 2.7.6 → 2.7.8
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/CHANGELOG +168 -0
- data/conf/auth.conf +5 -4
- data/conf/redhat/puppet.spec +16 -1
- data/conf/solaris/pkginfo +2 -2
- data/conf/suse/puppet.spec +9 -3
- data/ext/upload_facts.rb +120 -0
- data/install.rb +11 -16
- data/lib/puppet.rb +1 -1
- data/lib/puppet/application/agent.rb +0 -3
- data/lib/puppet/application/apply.rb +0 -3
- data/lib/puppet/application/queue.rb +21 -1
- data/lib/puppet/defaults.rb +6 -4
- data/lib/puppet/face/file/store.rb +1 -1
- data/lib/puppet/feature/base.rb +2 -1
- data/lib/puppet/file_bucket/dipper.rb +3 -2
- data/lib/puppet/file_serving/content.rb +1 -1
- data/lib/puppet/file_serving/metadata.rb +5 -2
- data/lib/puppet/indirector/facts/inventory_service.rb +20 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +3 -2
- data/lib/puppet/indirector/report/processor.rb +1 -1
- data/lib/puppet/network/handler/filebucket.rb +2 -0
- data/lib/puppet/network/handler/fileserver.rb +1 -1
- data/lib/puppet/network/handler/master.rb +1 -0
- data/lib/puppet/network/handler/report.rb +2 -0
- data/lib/puppet/network/handler/runner.rb +1 -0
- data/lib/puppet/network/handler/status.rb +2 -0
- data/lib/puppet/network/http/mongrel/rest.rb +8 -1
- data/lib/puppet/network/http_server.rb +3 -0
- data/lib/puppet/network/http_server/mongrel.rb +129 -0
- data/lib/puppet/network/rest_authconfig.rb +12 -4
- data/lib/puppet/parameter.rb +18 -0
- data/lib/puppet/parser/compiler.rb +1 -1
- data/lib/puppet/parser/grammar.ra +1 -1
- data/lib/puppet/parser/parser.rb +360 -350
- data/lib/puppet/property.rb +3 -3
- data/lib/puppet/provider/augeas/augeas.rb +1 -1
- data/lib/puppet/provider/exec/windows.rb +6 -7
- data/lib/puppet/provider/file/windows.rb +9 -2
- data/lib/puppet/provider/group/aix.rb +8 -8
- data/lib/puppet/provider/group/groupadd.rb +1 -3
- data/lib/puppet/provider/group/ldap.rb +8 -10
- data/lib/puppet/provider/group/windows_adsi.rb +8 -2
- data/lib/puppet/provider/package/aix.rb +1 -1
- data/lib/puppet/provider/package/macports.rb +3 -3
- data/lib/puppet/provider/package/msi.rb +12 -5
- data/lib/puppet/provider/package/nim.rb +1 -1
- data/lib/puppet/provider/package/pkgdmg.rb +3 -3
- data/lib/puppet/provider/package/ports.rb +1 -1
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +560 -0
- data/lib/puppet/provider/service/base.rb +2 -2
- data/lib/puppet/provider/service/bsd.rb +4 -3
- data/lib/puppet/provider/service/daemontools.rb +25 -25
- data/lib/puppet/provider/service/debian.rb +6 -4
- data/lib/puppet/provider/service/freebsd.rb +1 -1
- data/lib/puppet/provider/service/gentoo.rb +4 -3
- data/lib/puppet/provider/service/init.rb +3 -8
- data/lib/puppet/provider/service/launchd.rb +129 -96
- data/lib/puppet/provider/service/redhat.rb +2 -3
- data/lib/puppet/provider/service/runit.rb +20 -20
- data/lib/puppet/provider/service/smf.rb +8 -7
- data/lib/puppet/provider/service/src.rb +5 -6
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/service/upstart.rb +3 -5
- data/lib/puppet/provider/service/windows.rb +7 -7
- data/lib/puppet/provider/sshkey/parsed.rb +2 -3
- data/lib/puppet/provider/user/aix.rb +21 -21
- data/lib/puppet/provider/user/hpux.rb +3 -1
- data/lib/puppet/provider/user/ldap.rb +7 -7
- data/lib/puppet/provider/user/user_role_add.rb +10 -6
- data/lib/puppet/provider/user/useradd.rb +3 -1
- data/lib/puppet/provider/user/windows_adsi.rb +4 -3
- data/lib/puppet/rb_tree_map.rb +388 -0
- data/lib/puppet/reference/configuration.rb +7 -7
- data/lib/puppet/reference/indirection.rb +5 -6
- data/lib/puppet/reference/metaparameter.rb +3 -1
- data/lib/puppet/reference/network.rb +8 -8
- data/lib/puppet/reference/providers.rb +17 -21
- data/lib/puppet/reference/type.rb +12 -9
- data/lib/puppet/resource.rb +2 -5
- data/lib/puppet/resource/catalog.rb +1 -1
- data/lib/puppet/ssl/certificate_request.rb +70 -0
- data/lib/puppet/ssl/host.rb +6 -0
- data/lib/puppet/transaction.rb +158 -55
- data/lib/puppet/transaction/event_manager.rb +1 -1
- data/lib/puppet/type.rb +60 -30
- data/lib/puppet/type/augeas.rb +83 -49
- data/lib/puppet/type/computer.rb +1 -1
- data/lib/puppet/type/cron.rb +11 -11
- data/lib/puppet/type/exec.rb +28 -21
- data/lib/puppet/type/file.rb +17 -7
- data/lib/puppet/type/file/content.rb +2 -2
- data/lib/puppet/type/file/ensure.rb +15 -12
- data/lib/puppet/type/file/mode.rb +30 -5
- data/lib/puppet/type/file/source.rb +11 -10
- data/lib/puppet/type/file/target.rb +2 -2
- data/lib/puppet/type/filebucket.rb +1 -1
- data/lib/puppet/type/group.rb +4 -5
- data/lib/puppet/type/host.rb +1 -1
- data/lib/puppet/type/interface.rb +13 -10
- data/lib/puppet/type/k5login.rb +6 -6
- data/lib/puppet/type/macauthorization.rb +37 -36
- data/lib/puppet/type/maillist.rb +2 -2
- data/lib/puppet/type/mcx.rb +6 -6
- data/lib/puppet/type/mount.rb +3 -2
- data/lib/puppet/type/notify.rb +1 -1
- data/lib/puppet/type/package.rb +24 -23
- data/lib/puppet/type/router.rb +4 -1
- data/lib/puppet/type/schedule.rb +52 -44
- data/lib/puppet/type/scheduled_task.rb +222 -0
- data/lib/puppet/type/selmodule.rb +10 -6
- data/lib/puppet/type/service.rb +11 -11
- data/lib/puppet/type/ssh_authorized_key.rb +2 -5
- data/lib/puppet/type/sshkey.rb +1 -1
- data/lib/puppet/type/stage.rb +1 -1
- data/lib/puppet/type/tidy.rb +10 -8
- data/lib/puppet/type/user.rb +61 -53
- data/lib/puppet/type/vlan.rb +4 -4
- data/lib/puppet/type/whit.rb +6 -2
- data/lib/puppet/type/yumrepo.rb +33 -31
- data/lib/puppet/type/zfs.rb +34 -32
- data/lib/puppet/type/zone.rb +21 -19
- data/lib/puppet/type/zpool.rb +3 -3
- data/lib/puppet/util.rb +24 -6
- data/lib/puppet/util/adsi.rb +12 -7
- data/lib/puppet/util/checksums.rb +1 -1
- data/lib/puppet/util/diff.rb +1 -1
- data/lib/puppet/util/nagios_maker.rb +2 -2
- data/lib/puppet/util/reference.rb +16 -17
- data/lib/puppet/util/settings/file_setting.rb +14 -2
- data/lib/puppet/util/windows/security.rb +96 -32
- data/spec/integration/file_serving/terminus_helper_spec.rb +1 -1
- data/spec/integration/indirector/direct_file_server_spec.rb +9 -15
- data/spec/integration/indirector/file_content/file_server_spec.rb +1 -1
- data/spec/integration/indirector/file_metadata/file_server_spec.rb +1 -1
- data/spec/integration/provider/package_spec.rb +4 -0
- data/spec/integration/provider/service/init_spec.rb +8 -2
- data/spec/integration/reference/providers_spec.rb +1 -1
- data/spec/integration/ssl/certificate_request_spec.rb +1 -2
- data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -2
- data/spec/integration/ssl/host_spec.rb +1 -2
- data/spec/integration/transaction_spec.rb +25 -17
- data/spec/integration/type/exec_spec.rb +77 -0
- data/spec/integration/type/file_spec.rb +322 -2
- data/spec/integration/util/windows/security_spec.rb +393 -230
- data/spec/integration/util_spec.rb +16 -0
- data/spec/lib/puppet_spec/files.rb +3 -7
- data/spec/unit/application/apply_spec.rb +0 -9
- data/spec/unit/application/inspect_spec.rb +1 -0
- data/spec/unit/configurer/downloader_spec.rb +3 -3
- data/spec/unit/face/certificate_spec.rb +6 -2
- data/spec/unit/file_bucket/dipper_spec.rb +67 -10
- data/spec/unit/file_bucket/file_spec.rb +22 -28
- data/spec/unit/file_serving/content_spec.rb +1 -1
- data/spec/unit/file_serving/metadata_spec.rb +30 -3
- data/spec/unit/indirector/facts/inventory_service_spec.rb +22 -0
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +21 -24
- data/spec/unit/indirector/node/store_configs_spec.rb +1 -0
- data/spec/unit/indirector/resource/ral_spec.rb +1 -1
- data/spec/unit/indirector/resource_type/parser_spec.rb +2 -2
- data/spec/unit/indirector/rest_spec.rb +1 -1
- data/spec/unit/network/handler/ca_spec.rb +1 -1
- data/spec/unit/network/http/mongrel/rest_spec.rb +54 -25
- data/spec/unit/parameter_spec.rb +36 -0
- data/spec/unit/parser/parser_spec.rb +4 -0
- data/spec/unit/property_spec.rb +2 -2
- data/spec/unit/provider/exec/windows_spec.rb +2 -8
- data/spec/unit/provider/file/posix_spec.rb +6 -0
- data/spec/unit/provider/file/windows_spec.rb +18 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +22 -6
- data/spec/unit/provider/mount/parsed_spec.rb +1 -1
- data/spec/unit/provider/package/msi_spec.rb +2 -2
- data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +1571 -0
- data/spec/unit/provider/service/launchd_spec.rb +143 -130
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +5 -0
- data/spec/unit/provider/user/user_role_add_spec.rb +39 -9
- data/spec/unit/provider/user/useradd_spec.rb +1 -1
- data/spec/unit/provider/user/windows_adsi_spec.rb +8 -1
- data/spec/unit/rb_tree_map_spec.rb +572 -0
- data/spec/unit/resource/catalog_spec.rb +1 -1
- data/spec/unit/simple_graph_spec.rb +9 -9
- data/spec/unit/ssl/host_spec.rb +60 -12
- data/spec/unit/transaction/report_spec.rb +3 -3
- data/spec/unit/transaction_spec.rb +394 -11
- data/spec/unit/type/exec_spec.rb +35 -15
- data/spec/unit/type/file/content_spec.rb +11 -10
- data/spec/unit/type/file/mode_spec.rb +73 -19
- data/spec/unit/type/file/source_spec.rb +1 -1
- data/spec/unit/type/file_spec.rb +15 -0
- data/spec/unit/type/group_spec.rb +1 -1
- data/spec/unit/type/mount_spec.rb +5 -5
- data/spec/unit/type/resources_spec.rb +3 -3
- data/spec/unit/type/scheduled_task_spec.rb +102 -0
- data/spec/unit/type/ssh_authorized_key_spec.rb +2 -3
- data/spec/unit/type/user_spec.rb +2 -1
- data/spec/unit/type_spec.rb +48 -4
- data/spec/unit/util/adsi_spec.rb +18 -7
- data/spec/unit/util/checksums_spec.rb +20 -2
- data/spec/unit/util/execution_stub_spec.rb +10 -5
- data/spec/unit/util/logging_spec.rb +6 -6
- data/spec/unit/util/rdoc/parser_spec.rb +1 -1
- data/spec/unit/util/reference_spec.rb +29 -0
- data/spec/unit/util/settings/file_setting_spec.rb +8 -2
- data/spec/unit/util_spec.rb +115 -0
- data/test/other/transactions.rb +5 -11
- data/test/ral/type/exec.rb +1 -1
- metadata +24 -11
@@ -1,9 +1,8 @@
|
|
1
1
|
# Manage Red Hat services. Start/stop uses /sbin/service and enable/disable uses chkconfig
|
2
2
|
|
3
3
|
Puppet::Type.type(:service).provide :redhat, :parent => :init, :source => :init do
|
4
|
-
desc "Red Hat's (and probably many others) form of `init`-style service
|
5
|
-
|
6
|
-
Uses `chkconfig` for service enabling and disabling.
|
4
|
+
desc "Red Hat's (and probably many others') form of `init`-style service
|
5
|
+
management. Uses `chkconfig` for service enabling and disabling.
|
7
6
|
|
8
7
|
"
|
9
8
|
|
@@ -2,36 +2,36 @@
|
|
2
2
|
#
|
3
3
|
# author Brice Figureau <brice-puppet@daysofwonder.com>
|
4
4
|
Puppet::Type.type(:service).provide :runit, :parent => :daemontools do
|
5
|
-
desc
|
5
|
+
desc <<-EOT
|
6
|
+
Runit service management.
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
This provider manages daemons running supervised by Runit.
|
9
|
+
When detecting the service directory it will check, in order of preference:
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
* `/service`
|
12
|
+
* `/var/service`
|
13
|
+
* `/etc/service`
|
13
14
|
|
14
|
-
|
15
|
-
by default in:
|
15
|
+
The daemon directory should be in one of the following locations:
|
16
16
|
|
17
|
-
|
17
|
+
* `/etc/sv`
|
18
18
|
|
19
|
-
|
19
|
+
or this can be overriden in the service resource parameters::
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
service { "myservice":
|
22
|
+
provider => "runit",
|
23
|
+
path => "/path/to/daemons",
|
24
|
+
}
|
25
25
|
|
26
|
-
|
26
|
+
This provider supports out of the box:
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
* start/stop
|
29
|
+
* enable/disable
|
30
|
+
* restart
|
31
|
+
* status
|
32
32
|
|
33
33
|
|
34
|
-
|
34
|
+
EOT
|
35
35
|
|
36
36
|
commands :sv => "/usr/bin/sv"
|
37
37
|
|
@@ -1,15 +1,16 @@
|
|
1
1
|
# Solaris 10 SMF-style services.
|
2
2
|
Puppet::Type.type(:service).provide :smf, :parent => :base do
|
3
|
-
desc
|
3
|
+
desc <<-EOT
|
4
|
+
Support for Sun's new Service Management Framework.
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
Starting a service is effectively equivalent to enabling it, so there is
|
7
|
+
only support for starting and stopping services, which also enables and
|
8
|
+
disables them, respectively.
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
By specifying `manifest => "/path/to/service.xml"`, the SMF manifest will
|
11
|
+
be imported if it does not exist.
|
11
12
|
|
12
|
-
|
13
|
+
EOT
|
13
14
|
|
14
15
|
defaultfor :operatingsystem => :solaris
|
15
16
|
|
@@ -3,13 +3,12 @@ Puppet::Type.type(:service).provide :src, :parent => :base do
|
|
3
3
|
|
4
4
|
desc "Support for AIX's System Resource controller.
|
5
5
|
|
6
|
-
Services are started/stopped based on the stopsrc and startsrc
|
7
|
-
commands, and some services can be refreshed with refresh command.
|
6
|
+
Services are started/stopped based on the `stopsrc` and `startsrc`
|
7
|
+
commands, and some services can be refreshed with `refresh` command.
|
8
8
|
|
9
|
-
|
10
|
-
modifications to
|
11
|
-
|
12
|
-
* Starting and stopping groups of subsystems is not yet supported
|
9
|
+
Enabling and disabling services is not supported, as it requires
|
10
|
+
modifications to `/etc/inittab`. Starting and stopping groups of subsystems
|
11
|
+
is not yet supported.
|
13
12
|
"
|
14
13
|
|
15
14
|
defaultfor :operatingsystem => :aix
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Manage systemd services using /bin/systemctl
|
2
2
|
|
3
3
|
Puppet::Type.type(:service).provide :systemd, :parent => :base do
|
4
|
-
desc "
|
4
|
+
desc "Manages `systemd` services using `/bin/systemctl`."
|
5
5
|
|
6
6
|
commands :systemctl => "/bin/systemctl"
|
7
7
|
|
@@ -1,10 +1,8 @@
|
|
1
1
|
Puppet::Type.type(:service).provide :upstart, :parent => :init do
|
2
|
-
desc "Ubuntu service
|
2
|
+
desc "Ubuntu service management with `upstart`.
|
3
3
|
|
4
|
-
This provider manages upstart jobs which have replaced initd
|
5
|
-
|
6
|
-
See:
|
7
|
-
* http://upstart.ubuntu.com/
|
4
|
+
This provider manages `upstart` jobs, which have replaced `initd` services
|
5
|
+
on Ubuntu. For `upstart` documentation, see <http://upstart.ubuntu.com/>.
|
8
6
|
"
|
9
7
|
# confine to :ubuntu for now because I haven't tested on other platforms
|
10
8
|
confine :operatingsystem => :ubuntu #[:ubuntu, :fedora, :debian]
|
@@ -4,16 +4,16 @@ require 'win32/service' if Puppet.features.microsoft_windows?
|
|
4
4
|
|
5
5
|
Puppet::Type.type(:service).provide :windows do
|
6
6
|
|
7
|
-
desc
|
7
|
+
desc <<-EOT
|
8
|
+
Support for Windows Service Control Manager (SCM).
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
* Control of service groups (dependencies) is not yet supported."
|
10
|
+
Services are controlled according to the capabilities of the `win32-service`
|
11
|
+
gem. All SCM operations (start/stop/enable/disable/query) are supported.
|
12
|
+
Control of service groups (dependencies) is not yet supported.
|
13
|
+
EOT
|
14
14
|
|
15
15
|
defaultfor :operatingsystem => :windows
|
16
|
-
confine
|
16
|
+
confine :operatingsystem => :windows
|
17
17
|
|
18
18
|
has_feature :refreshable
|
19
19
|
|
@@ -8,11 +8,10 @@ else
|
|
8
8
|
end
|
9
9
|
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
Puppet::Type.type(:sshkey).provide(
|
12
|
+
:parsed,
|
13
13
|
:parent => Puppet::Provider::ParsedFile,
|
14
14
|
:default_target => known,
|
15
|
-
|
16
15
|
:filetype => :flat
|
17
16
|
) do
|
18
17
|
desc "Parse and generate host-wide known hosts files for SSH."
|
@@ -17,7 +17,7 @@ require 'tempfile'
|
|
17
17
|
require 'date'
|
18
18
|
|
19
19
|
Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
20
|
-
desc "User management for AIX
|
20
|
+
desc "User management for AIX."
|
21
21
|
|
22
22
|
# This will the the default provider for this platform
|
23
23
|
defaultfor :operatingsystem => :aix
|
@@ -28,7 +28,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
28
28
|
commands :add => "/usr/bin/mkuser"
|
29
29
|
commands :delete => "/usr/sbin/rmuser"
|
30
30
|
commands :modify => "/usr/bin/chuser"
|
31
|
-
|
31
|
+
|
32
32
|
commands :lsgroup => "/usr/sbin/lsgroup"
|
33
33
|
commands :chpasswd => "/bin/chpasswd"
|
34
34
|
|
@@ -52,7 +52,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# AIX attributes to properties mapping.
|
55
|
-
#
|
55
|
+
#
|
56
56
|
# Valid attributes to be managed by this provider.
|
57
57
|
# It is a list with of hash
|
58
58
|
# :aix_attr AIX command attribute name
|
@@ -73,10 +73,10 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
73
73
|
{:aix_attr => :minage, :puppet_prop => :password_min_age},
|
74
74
|
{:aix_attr => :attributes, :puppet_prop => :attributes},
|
75
75
|
]
|
76
|
-
|
76
|
+
|
77
77
|
#--------------
|
78
78
|
# Command definition
|
79
|
-
|
79
|
+
|
80
80
|
# Return the IA module arguments based on the resource param ia_load_module
|
81
81
|
def get_ia_module_args
|
82
82
|
if @resource[:ia_load_module]
|
@@ -85,7 +85,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
85
85
|
[]
|
86
86
|
end
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
# List groups and Ids
|
90
90
|
def lsgroupscmd(value=@resource[:name])
|
91
91
|
[command(:lsgroup)] +
|
@@ -116,7 +116,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
116
116
|
def modifycmd(hash = property_hash)
|
117
117
|
args = self.hash2args(hash)
|
118
118
|
return nil if args.empty?
|
119
|
-
|
119
|
+
|
120
120
|
[self.class.command(:modify)] + self.get_ia_module_args +
|
121
121
|
args + [@resource[:name]]
|
122
122
|
end
|
@@ -131,9 +131,9 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
131
131
|
super
|
132
132
|
# Reset the password if needed
|
133
133
|
self.password = @resource[:password] if @resource[:password]
|
134
|
-
end
|
134
|
+
end
|
135
|
+
|
135
136
|
|
136
|
-
|
137
137
|
def get_arguments(key, value, mapping, objectinfo)
|
138
138
|
# In the case of attributes, return a list of key=vlaue
|
139
139
|
if key == :attributes
|
@@ -141,10 +141,10 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
141
141
|
unless value and value.is_a? Hash
|
142
142
|
return value.select { |k,v| true }.map { |pair| pair.join("=") }
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
super(key, value, mapping, objectinfo)
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
148
|
# Get the groupname from its id
|
149
149
|
def self.groupname_by_id(gid)
|
150
150
|
groupname=nil
|
@@ -165,16 +165,16 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
165
165
|
|
166
166
|
# Check that a group exists and is valid
|
167
167
|
def verify_group(value)
|
168
|
-
if value.is_a? Integer or value.is_a? Fixnum
|
168
|
+
if value.is_a? Integer or value.is_a? Fixnum
|
169
169
|
groupname = self.groupname_by_id(value)
|
170
170
|
raise ArgumentError, "AIX group must be a valid existing group" unless groupname
|
171
|
-
else
|
171
|
+
else
|
172
172
|
raise ArgumentError, "AIX group must be a valid existing group" unless groupid_by_name(value)
|
173
173
|
groupname = value
|
174
174
|
end
|
175
175
|
groupname
|
176
176
|
end
|
177
|
-
|
177
|
+
|
178
178
|
# The user's primary group. Can be specified numerically or by name.
|
179
179
|
def gid_to_attr(value)
|
180
180
|
verify_group(value)
|
@@ -186,7 +186,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
186
186
|
end
|
187
187
|
|
188
188
|
# The expiry date for this user. Must be provided in
|
189
|
-
# a zero padded YYYY-MM-DD HH:MM format
|
189
|
+
# a zero padded YYYY-MM-DD HH:MM format
|
190
190
|
def expiry_to_attr(value)
|
191
191
|
# For chuser the expires parameter is a 10-character string in the MMDDhhmmyy format
|
192
192
|
# that is,"%m%d%H%M%y"
|
@@ -197,7 +197,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
197
197
|
end
|
198
198
|
newdate
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
201
|
def expiry_from_attr(value)
|
202
202
|
if value =~ /(..)(..)(..)(..)(..)/
|
203
203
|
#d= DateTime.parse("20#{$5}-#{$1}-#{$2} #{$3}:#{$4}")
|
@@ -233,7 +233,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
233
233
|
if ! f.eof?
|
234
234
|
f.each { |l|
|
235
235
|
# If there is a new user stanza, stop
|
236
|
-
break if l =~ /^\S*:\s*$/
|
236
|
+
break if l =~ /^\S*:\s*$/
|
237
237
|
# If the password= entry is found, return it
|
238
238
|
if l =~ /^\s*password\s*=\s*(.*)$/
|
239
239
|
password = $1; break;
|
@@ -242,11 +242,11 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
242
242
|
end
|
243
243
|
f.close()
|
244
244
|
return password
|
245
|
-
end
|
245
|
+
end
|
246
246
|
|
247
247
|
def password=(value)
|
248
248
|
user = @resource[:name]
|
249
|
-
|
249
|
+
|
250
250
|
# Puppet execute does not support strings as input, only files.
|
251
251
|
tmpfile = Tempfile.new('puppet_#{user}_pw')
|
252
252
|
tmpfile << "#{user}:#{value}\n"
|
@@ -264,7 +264,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
264
264
|
ensure
|
265
265
|
tmpfile.delete()
|
266
266
|
end
|
267
|
-
end
|
267
|
+
end
|
268
268
|
|
269
269
|
def filter_attributes(hash)
|
270
270
|
# Return only not managed attributtes.
|
@@ -284,7 +284,7 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
284
284
|
#self.class.validate(param, value)
|
285
285
|
param = :attributes
|
286
286
|
cmd = modifycmd({param => filter_attributes(attr_hash)})
|
287
|
-
if cmd
|
287
|
+
if cmd
|
288
288
|
begin
|
289
289
|
execute(cmd)
|
290
290
|
rescue Puppet::ExecutionFailure => detail
|
@@ -1,5 +1,7 @@
|
|
1
1
|
Puppet::Type.type(:user).provide :hpuxuseradd, :parent => :useradd do
|
2
|
-
desc "User management for
|
2
|
+
desc "User management for HP-UX. This provider uses the undocumented `-F`
|
3
|
+
switch to HP-UX's special `usermod` binary to work around the fact that
|
4
|
+
its standard `usermod` cannot make changes while the user is logged in."
|
3
5
|
|
4
6
|
defaultfor :operatingsystem => "hp-ux"
|
5
7
|
confine :operatingsystem => "hp-ux"
|
@@ -1,16 +1,16 @@
|
|
1
1
|
require 'puppet/provider/ldap'
|
2
2
|
|
3
3
|
Puppet::Type.type(:user).provide :ldap, :parent => Puppet::Provider::Ldap do
|
4
|
-
desc "User management via
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
desc "User management via LDAP.
|
5
|
+
|
6
|
+
This provider requires that you have valid values for all of the
|
7
|
+
LDAP-related settings in `puppet.conf`, including `ldapbase`. You will
|
8
|
+
almost definitely need settings for `ldapuser` and `ldappassword` in order
|
9
|
+
for your clients to write to LDAP.
|
9
10
|
|
10
11
|
Note that this provider will automatically generate a UID for you if
|
11
12
|
you do not specify one, but it is a potentially expensive operation,
|
12
|
-
as it iterates across all existing users to pick the appropriate next
|
13
|
-
one."
|
13
|
+
as it iterates across all existing users to pick the appropriate next one."
|
14
14
|
|
15
15
|
confine :feature => :ldap, :false => (Puppet[:ldapuser] == "")
|
16
16
|
|
@@ -2,7 +2,7 @@ require 'puppet/util/user_attr'
|
|
2
2
|
|
3
3
|
Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source => :useradd do
|
4
4
|
|
5
|
-
desc "User management
|
5
|
+
desc "User and role management on Solaris, via `useradd` and `roleadd`."
|
6
6
|
|
7
7
|
defaultfor :operatingsystem => :solaris
|
8
8
|
|
@@ -168,25 +168,29 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
|
|
168
168
|
#Smooth like 80 grit
|
169
169
|
def password=(cryptopw)
|
170
170
|
begin
|
171
|
-
File.open(
|
172
|
-
File.open("
|
171
|
+
File.open(shadow_file, "r") do |shadow|
|
172
|
+
File.open("#{shadow_file}_tmp", "w", 0600) do |shadow_tmp|
|
173
173
|
while line = shadow.gets
|
174
174
|
line_arr = line.split(':')
|
175
175
|
if line_arr[0] == @resource[:name]
|
176
176
|
line_arr[1] = cryptopw
|
177
|
+
line_arr[2] = Time.now().to_i / 86400
|
177
178
|
line = line_arr.join(':')
|
178
179
|
end
|
179
180
|
shadow_tmp.print line
|
180
181
|
end
|
181
182
|
end
|
182
183
|
end
|
183
|
-
File.rename("
|
184
|
+
File.rename("#{shadow_file}_tmp", shadow_file)
|
184
185
|
rescue => detail
|
185
186
|
fail "Could not write temporary shadow file: #{detail}"
|
186
187
|
ensure
|
187
188
|
# Make sure this *always* gets deleted
|
188
|
-
File.unlink("
|
189
|
+
File.unlink("#{shadow_file}_tmp") if File.exist?("#{shadow_file}_tmp")
|
189
190
|
end
|
190
191
|
end
|
191
|
-
end
|
192
192
|
|
193
|
+
private
|
194
|
+
|
195
|
+
def shadow_file; '/etc/shadow'; end
|
196
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'puppet/provider/nameservice/objectadd'
|
2
2
|
|
3
3
|
Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameService::ObjectAdd do
|
4
|
-
desc "User management via `useradd` and its ilk. Note that you will need to
|
4
|
+
desc "User management via `useradd` and its ilk. Note that you will need to
|
5
|
+
install Ruby's shadow password library (often known as `ruby-libshadow`)
|
6
|
+
if you wish to manage user passwords."
|
5
7
|
|
6
8
|
commands :add => "useradd", :delete => "userdel", :modify => "usermod", :password => "chage"
|
7
9
|
|
@@ -1,11 +1,10 @@
|
|
1
1
|
require 'puppet/util/adsi'
|
2
2
|
|
3
3
|
Puppet::Type.type(:user).provide :windows_adsi do
|
4
|
-
desc "User management for Windows"
|
4
|
+
desc "User management for Windows."
|
5
5
|
|
6
6
|
defaultfor :operatingsystem => :windows
|
7
|
-
confine
|
8
|
-
confine :feature => :microsoft_windows
|
7
|
+
confine :operatingsystem => :windows
|
9
8
|
|
10
9
|
has_features :manages_homedir, :manages_passwords
|
11
10
|
|
@@ -23,6 +22,8 @@ Puppet::Type.type(:user).provide :windows_adsi do
|
|
23
22
|
|
24
23
|
def create
|
25
24
|
@user = Puppet::Util::ADSI::User.create(@resource[:name])
|
25
|
+
@user.commit
|
26
|
+
|
26
27
|
[:comment, :home, :groups].each do |prop|
|
27
28
|
send("#{prop}=", @resource[prop]) if @resource[prop]
|
28
29
|
end
|
@@ -0,0 +1,388 @@
|
|
1
|
+
# Algorithms and Containers project is Copyright (c) 2009 Kanwei Li
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
# SOFTWARE.
|
20
|
+
#
|
21
|
+
# A RbTreeMap is a map that is stored in sorted order based on the order of its keys. This ordering is
|
22
|
+
# determined by applying the function <=> to compare the keys. No duplicate values for keys are allowed,
|
23
|
+
# so duplicate values are overwritten.
|
24
|
+
#
|
25
|
+
# A major advantage of RBTreeMap over a Hash is the fact that keys are stored in order and can thus be
|
26
|
+
# iterated over in order. This is useful for many datasets.
|
27
|
+
#
|
28
|
+
# The implementation is adapted from Robert Sedgewick's Left Leaning Red-Black Tree implementation,
|
29
|
+
# which can be found at http://www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
|
30
|
+
#
|
31
|
+
# Most methods have O(log n) complexity.
|
32
|
+
|
33
|
+
class Puppet::RbTreeMap
|
34
|
+
include Enumerable
|
35
|
+
|
36
|
+
attr_reader :size
|
37
|
+
|
38
|
+
alias_method :length, :size
|
39
|
+
|
40
|
+
# Create and initialize a new empty TreeMap.
|
41
|
+
def initialize
|
42
|
+
@root = nil
|
43
|
+
@size = 0
|
44
|
+
end
|
45
|
+
|
46
|
+
# Insert an item with an associated key into the TreeMap, and returns the item inserted
|
47
|
+
#
|
48
|
+
# Complexity: O(log n)
|
49
|
+
#
|
50
|
+
# map = Containers::TreeMap.new
|
51
|
+
# map.push("MA", "Massachusetts") #=> "Massachusetts"
|
52
|
+
# map.get("MA") #=> "Massachusetts"
|
53
|
+
def push(key, value)
|
54
|
+
@root = insert(@root, key, value)
|
55
|
+
@root.color = :black
|
56
|
+
value
|
57
|
+
end
|
58
|
+
alias_method :[]=, :push
|
59
|
+
|
60
|
+
# Return true if key is found in the TreeMap, false otherwise
|
61
|
+
#
|
62
|
+
# Complexity: O(log n)
|
63
|
+
#
|
64
|
+
# map = Containers::TreeMap.new
|
65
|
+
# map.push("MA", "Massachusetts")
|
66
|
+
# map.push("GA", "Georgia")
|
67
|
+
# map.has_key?("GA") #=> true
|
68
|
+
# map.has_key?("DE") #=> false
|
69
|
+
def has_key?(key)
|
70
|
+
!get_recursive(@root, key).nil?
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return the item associated with the key, or nil if none found.
|
74
|
+
#
|
75
|
+
# Complexity: O(log n)
|
76
|
+
#
|
77
|
+
# map = Containers::TreeMap.new
|
78
|
+
# map.push("MA", "Massachusetts")
|
79
|
+
# map.push("GA", "Georgia")
|
80
|
+
# map.get("GA") #=> "Georgia"
|
81
|
+
def get(key)
|
82
|
+
node = get_recursive(@root, key)
|
83
|
+
node ? node.value : nil
|
84
|
+
node.value if node
|
85
|
+
end
|
86
|
+
alias_method :[], :get
|
87
|
+
|
88
|
+
# Return the smallest key in the map.
|
89
|
+
#
|
90
|
+
# Complexity: O(log n)
|
91
|
+
#
|
92
|
+
# map = Containers::TreeMap.new
|
93
|
+
# map.push("MA", "Massachusetts")
|
94
|
+
# map.push("GA", "Georgia")
|
95
|
+
# map.min_key #=> "GA"
|
96
|
+
def min_key
|
97
|
+
@root.nil? ? nil : min_recursive(@root).key
|
98
|
+
end
|
99
|
+
|
100
|
+
# Return the largest key in the map.
|
101
|
+
#
|
102
|
+
# Complexity: O(log n)
|
103
|
+
#
|
104
|
+
# map = Containers::TreeMap.new
|
105
|
+
# map.push("MA", "Massachusetts")
|
106
|
+
# map.push("GA", "Georgia")
|
107
|
+
# map.max_key #=> "MA"
|
108
|
+
def max_key
|
109
|
+
@root.nil? ? nil : max_recursive(@root).key
|
110
|
+
end
|
111
|
+
|
112
|
+
# Deletes the item and key if it's found, and returns the item. Returns nil
|
113
|
+
# if key is not present.
|
114
|
+
#
|
115
|
+
# Complexity: O(log n)
|
116
|
+
#
|
117
|
+
# map = Containers::TreeMap.new
|
118
|
+
# map.push("MA", "Massachusetts")
|
119
|
+
# map.push("GA", "Georgia")
|
120
|
+
# map.delete("MA") #=> "Massachusetts"
|
121
|
+
def delete(key)
|
122
|
+
result = nil
|
123
|
+
if @root
|
124
|
+
return unless has_key? key
|
125
|
+
@root, result = delete_recursive(@root, key)
|
126
|
+
@root.color = :black if @root
|
127
|
+
@size -= 1
|
128
|
+
end
|
129
|
+
result
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns true if the tree is empty, false otherwise
|
133
|
+
def empty?
|
134
|
+
@root.nil?
|
135
|
+
end
|
136
|
+
|
137
|
+
# Deletes the item with the smallest key and returns the item. Returns nil
|
138
|
+
# if key is not present.
|
139
|
+
#
|
140
|
+
# Complexity: O(log n)
|
141
|
+
#
|
142
|
+
# map = Containers::TreeMap.new
|
143
|
+
# map.push("MA", "Massachusetts")
|
144
|
+
# map.push("GA", "Georgia")
|
145
|
+
# map.delete_min #=> "Massachusetts"
|
146
|
+
# map.size #=> 1
|
147
|
+
def delete_min
|
148
|
+
result = nil
|
149
|
+
if @root
|
150
|
+
@root, result = delete_min_recursive(@root)
|
151
|
+
@root.color = :black if @root
|
152
|
+
@size -= 1
|
153
|
+
end
|
154
|
+
result
|
155
|
+
end
|
156
|
+
|
157
|
+
# Deletes the item with the largest key and returns the item. Returns nil
|
158
|
+
# if key is not present.
|
159
|
+
#
|
160
|
+
# Complexity: O(log n)
|
161
|
+
#
|
162
|
+
# map = Containers::TreeMap.new
|
163
|
+
# map.push("MA", "Massachusetts")
|
164
|
+
# map.push("GA", "Georgia")
|
165
|
+
# map.delete_max #=> "Georgia"
|
166
|
+
# map.size #=> 1
|
167
|
+
def delete_max
|
168
|
+
result = nil
|
169
|
+
if @root
|
170
|
+
@root, result = delete_max_recursive(@root)
|
171
|
+
@root.color = :black if @root
|
172
|
+
@size -= 1
|
173
|
+
end
|
174
|
+
result
|
175
|
+
end
|
176
|
+
|
177
|
+
# Yields [key, value] pairs in order by key.
|
178
|
+
def each(&blk)
|
179
|
+
recursive_yield(@root, &blk)
|
180
|
+
end
|
181
|
+
|
182
|
+
def first
|
183
|
+
return nil unless @root
|
184
|
+
node = min_recursive(@root)
|
185
|
+
[node.key, node.value]
|
186
|
+
end
|
187
|
+
|
188
|
+
def last
|
189
|
+
return nil unless @root
|
190
|
+
node = max_recursive(@root)
|
191
|
+
[node.key, node.value]
|
192
|
+
end
|
193
|
+
|
194
|
+
def to_hash
|
195
|
+
@root ? @root.to_hash : {}
|
196
|
+
end
|
197
|
+
|
198
|
+
class Node # :nodoc: all
|
199
|
+
attr_accessor :color, :key, :value, :left, :right
|
200
|
+
def initialize(key, value)
|
201
|
+
@key = key
|
202
|
+
@value = value
|
203
|
+
@color = :red
|
204
|
+
@left = nil
|
205
|
+
@right = nil
|
206
|
+
end
|
207
|
+
|
208
|
+
def to_hash
|
209
|
+
h = {
|
210
|
+
:node => {
|
211
|
+
:key => @key,
|
212
|
+
:value => @value,
|
213
|
+
:color => @color,
|
214
|
+
}
|
215
|
+
}
|
216
|
+
h.merge!(:left => left.to_hash) if @left
|
217
|
+
h.merge!(:right => right.to_hash) if @right
|
218
|
+
h
|
219
|
+
end
|
220
|
+
|
221
|
+
def red?
|
222
|
+
@color == :red
|
223
|
+
end
|
224
|
+
|
225
|
+
def colorflip
|
226
|
+
@color = @color == :red ? :black : :red
|
227
|
+
@left.color = @left.color == :red ? :black : :red
|
228
|
+
@right.color = @right.color == :red ? :black : :red
|
229
|
+
end
|
230
|
+
|
231
|
+
def rotate_left
|
232
|
+
r = @right
|
233
|
+
r_key, r_value, r_color = r.key, r.value, r.color
|
234
|
+
b = r.left
|
235
|
+
r.left = @left
|
236
|
+
@left = r
|
237
|
+
@right = r.right
|
238
|
+
r.right = b
|
239
|
+
r.color, r.key, r.value = :red, @key, @value
|
240
|
+
@key, @value = r_key, r_value
|
241
|
+
self
|
242
|
+
end
|
243
|
+
|
244
|
+
def rotate_right
|
245
|
+
l = @left
|
246
|
+
l_key, l_value, l_color = l.key, l.value, l.color
|
247
|
+
b = l.right
|
248
|
+
l.right = @right
|
249
|
+
@right = l
|
250
|
+
@left = l.left
|
251
|
+
l.left = b
|
252
|
+
l.color, l.key, l.value = :red, @key, @value
|
253
|
+
@key, @value = l_key, l_value
|
254
|
+
self
|
255
|
+
end
|
256
|
+
|
257
|
+
def move_red_left
|
258
|
+
colorflip
|
259
|
+
if (@right.left && @right.left.red?)
|
260
|
+
@right.rotate_right
|
261
|
+
rotate_left
|
262
|
+
colorflip
|
263
|
+
end
|
264
|
+
self
|
265
|
+
end
|
266
|
+
|
267
|
+
def move_red_right
|
268
|
+
colorflip
|
269
|
+
if (@left.left && @left.left.red?)
|
270
|
+
rotate_right
|
271
|
+
colorflip
|
272
|
+
end
|
273
|
+
self
|
274
|
+
end
|
275
|
+
|
276
|
+
def fixup
|
277
|
+
rotate_left if @right && @right.red?
|
278
|
+
rotate_right if (@left && @left.red?) && (@left.left && @left.left.red?)
|
279
|
+
colorflip if (@left && @left.red?) && (@right && @right.red?)
|
280
|
+
|
281
|
+
self
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
private
|
286
|
+
|
287
|
+
def recursive_yield(node, &blk)
|
288
|
+
return unless node
|
289
|
+
recursive_yield(node.left, &blk)
|
290
|
+
yield node.key, node.value
|
291
|
+
recursive_yield(node.right, &blk)
|
292
|
+
end
|
293
|
+
|
294
|
+
def delete_recursive(node, key)
|
295
|
+
if (key <=> node.key) == -1
|
296
|
+
node.move_red_left if ( !isred(node.left) && !isred(node.left.left) )
|
297
|
+
node.left, result = delete_recursive(node.left, key)
|
298
|
+
else
|
299
|
+
node.rotate_right if isred(node.left)
|
300
|
+
if ( ( (key <=> node.key) == 0) && node.right.nil? )
|
301
|
+
return nil, node.value
|
302
|
+
end
|
303
|
+
if ( !isred(node.right) && !isred(node.right.left) )
|
304
|
+
node.move_red_right
|
305
|
+
end
|
306
|
+
if (key <=> node.key) == 0
|
307
|
+
result = node.value
|
308
|
+
min_child = min_recursive(node.right)
|
309
|
+
node.value = min_child.value
|
310
|
+
node.key = min_child.key
|
311
|
+
node.right = delete_min_recursive(node.right).first
|
312
|
+
else
|
313
|
+
node.right, result = delete_recursive(node.right, key)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
return node.fixup, result
|
317
|
+
end
|
318
|
+
|
319
|
+
def delete_min_recursive(node)
|
320
|
+
if node.left.nil?
|
321
|
+
return nil, node.value
|
322
|
+
end
|
323
|
+
if ( !isred(node.left) && !isred(node.left.left) )
|
324
|
+
node.move_red_left
|
325
|
+
end
|
326
|
+
node.left, result = delete_min_recursive(node.left)
|
327
|
+
|
328
|
+
return node.fixup, result
|
329
|
+
end
|
330
|
+
|
331
|
+
def delete_max_recursive(node)
|
332
|
+
if (isred(node.left))
|
333
|
+
node = node.rotate_right
|
334
|
+
end
|
335
|
+
return nil, node.value if node.right.nil?
|
336
|
+
if ( !isred(node.right) && !isred(node.right.left) )
|
337
|
+
node.move_red_right
|
338
|
+
end
|
339
|
+
node.right, result = delete_max_recursive(node.right)
|
340
|
+
|
341
|
+
return node.fixup, result
|
342
|
+
end
|
343
|
+
|
344
|
+
def get_recursive(node, key)
|
345
|
+
return nil if node.nil?
|
346
|
+
case key <=> node.key
|
347
|
+
when 0 then return node
|
348
|
+
when -1 then return get_recursive(node.left, key)
|
349
|
+
when 1 then return get_recursive(node.right, key)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def min_recursive(node)
|
354
|
+
return node if node.left.nil?
|
355
|
+
|
356
|
+
min_recursive(node.left)
|
357
|
+
end
|
358
|
+
|
359
|
+
def max_recursive(node)
|
360
|
+
return node if node.right.nil?
|
361
|
+
|
362
|
+
max_recursive(node.right)
|
363
|
+
end
|
364
|
+
|
365
|
+
def insert(node, key, value)
|
366
|
+
unless node
|
367
|
+
@size += 1
|
368
|
+
return Node.new(key, value)
|
369
|
+
end
|
370
|
+
|
371
|
+
case key <=> node.key
|
372
|
+
when 0 then node.value = value
|
373
|
+
when -1 then node.left = insert(node.left, key, value)
|
374
|
+
when 1 then node.right = insert(node.right, key, value)
|
375
|
+
end
|
376
|
+
|
377
|
+
node.rotate_left if (node.right && node.right.red?)
|
378
|
+
node.rotate_right if (node.left && node.left.red? && node.left.left && node.left.left.red?)
|
379
|
+
node.colorflip if (node.left && node.left.red? && node.right && node.right.red?)
|
380
|
+
node
|
381
|
+
end
|
382
|
+
|
383
|
+
def isred(node)
|
384
|
+
return false if node.nil?
|
385
|
+
|
386
|
+
node.color == :red
|
387
|
+
end
|
388
|
+
end
|