1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
require 'puppet'
require 'puppet/application'
require 'facter'
Puppet::Application.new(:resource) do
should_not_parse_config
attr_accessor :host, :extra_params
preinit do
@extra_params = []
@host = nil
Facter.loadfacts
end
option("--debug","-d")
option("--verbose","-v")
option("--edit","-e")
option("--host HOST","-H") do |arg|
@host = arg
end
option("--types", "-t") do |arg|
types = []
Puppet::Type.loadall
Puppet::Type.eachtype do |t|
next if t.name == :component
types << t.name.to_s
end
puts types.sort
exit
end
option("--param PARAM", "-p") do |arg|
@extra_params << arg.to_sym
end
command(:main) do
type = ARGV.shift or raise "You must specify the type to display"
typeobj = Puppet::Type.type(type) or raise "Could not find type #{type}"
name = ARGV.shift
params = {}
ARGV.each do |setting|
if setting =~ /^(\w+)=(.+)$/
params[$1] = $2
else
raise "Invalid parameter setting %s" % setting
end
end
if options[:edit] and @host
raise "You cannot edit a remote host"
end
properties = typeobj.properties.collect { |s| s.name }
format = proc {|trans|
trans.dup.collect do |param, value|
if value.nil? or value.to_s.empty?
trans.delete(param)
elsif value.to_s == "absent" and param.to_s != "ensure"
trans.delete(param)
end
unless properties.include?(param) or @extra_params.include?(param)
trans.delete(param)
end
end
trans.to_manifest
}
text = if @host
client = Puppet::Network::Client.resource.new(:Server => @host, :Port => Puppet[:puppetport])
unless client.read_cert
raise "client.read_cert failed"
end
begin
# They asked for a single resource.
if name
transbucket = [client.describe(type, name)]
else
# Else, list the whole thing out.
transbucket = client.instances(type)
end
rescue Puppet::Network::XMLRPCClientError => exc
raise "client.list(#{type}) failed: #{exc.message}"
end
transbucket.sort { |a,b| a.name <=> b.name }.collect(&format)
else
if name
obj = typeobj.instances.find { |o| o.name == name } || typeobj.new(:name => name, :check => properties)
vals = obj.retrieve
unless params.empty?
params.each do |param, value|
obj[param] = value
end
catalog = Puppet::Resource::Catalog.new
catalog.add_resource obj
begin
catalog.apply
rescue => detail
if Puppet[:trace]
puts detail.backtrace
end
end
end
[format.call(obj.to_trans(true))]
else
typeobj.instances.collect do |obj|
next if ARGV.length > 0 and ! ARGV.include? obj.name
trans = obj.to_trans(true)
format.call(trans)
end
end
end.compact.join("\n")
if options[:edit]
file = "/tmp/x2puppet-#{Process.pid}.pp"
begin
File.open(file, "w") do |f|
f.puts text
end
ENV["EDITOR"] ||= "vi"
system(ENV["EDITOR"], file)
system("puppet -v " + file)
ensure
#if FileTest.exists? file
# File.unlink(file)
#end
end
else
puts text
end
end
setup do
Puppet::Util::Log.newdestination(:console)
# Now parse the config
Puppet.parse_config
if options[:debug]
Puppet::Util::Log.level = :debug
elsif options[:verbose]
Puppet::Util::Log.level = :info
end
end
end
|