promotion 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,4 @@
1
-
2
- == Version 1.3.0
1
+ == Version 1.3.1
3
2
  - Added generation of newsyslog.conf
4
3
  - Added some more examples into the shell generated by mkdeploy
5
4
  - eliminated ERB, replacing it with plain text generation
@@ -0,0 +1,69 @@
1
+ module Promotion
2
+ module Generator
3
+ module Crontab
4
+
5
+ # The crontab for each user must be deployed using the crontab tool
6
+ def self.generate(specs)
7
+ sym = "Crontab"
8
+ begin
9
+ schedules = {} # keyed on user, value is array of schedule elements
10
+ specs.each { |spec|
11
+ spec.elements.each("/Specification/Crontab/Schedule") { |sched|
12
+ user = sched.attributes["User"]
13
+ schedules[user] = [] unless schedules.has_key?(user)
14
+ schedules[user] << sched
15
+ }
16
+ }
17
+ schedules.each { |user, crontablist|
18
+ generatedContents = self.contents(user, crontablist)
19
+ userCrontab = File.expand_path(user, Folders::Crontabs)
20
+ begin
21
+ tempFilename = user + ".tmp"
22
+ tempFile = File.new(tempFilename, File::WRONLY | File::CREAT | File::TRUNC)
23
+ tempFile.puts(generatedContents)
24
+ # previous cron jobs are *NOT* preserved - the tab is competely generated!
25
+ # otherwise we accumulate the cron-generated warning messages at the top of the file
26
+ ensure
27
+ tempFile.close unless tempFile.nil? || tempFile.closed?
28
+ end
29
+ $log.info("Checking temporary crontab written to #{tempFilename}.")
30
+ crontabResults = `#{Files::Crontab} -u #{user} #{tempFilename}`
31
+ if $?.exitstatus == 0
32
+ $log.info("crontab confirms that crontab syntax is correct for user #{user}.")
33
+ else
34
+ $log.error(crontabResults)
35
+ raise
36
+ end
37
+ FileUtils.rm_f(tempFilename)
38
+ $log.info("New crontab installed for user #{user}")
39
+ }
40
+ rescue => e
41
+ $log.error("Error occurred while generating crontab\n#{e.message}" + e.backtrace.join("\n"))
42
+ exit 1
43
+ end
44
+ end
45
+
46
+ # Generates the contents for /var/cron/tabs/{user}, containing scheduled jobs
47
+ def self.contents(user, crontablist)
48
+ contents = []
49
+ contents << "# /var/cron/tabs/#{user} - #{user}'s crontab \n#\n"
50
+ contents << "#minute hour mday month wday command\n#\n\n"
51
+ crontablist.each { |sched|
52
+ if sched.attributes["Comment"]
53
+ contents << "#______________________________\n"
54
+ contents << "#{sched.attributes["Comment"]} \n"
55
+ end
56
+ minute = sched.attributes["Minute"] || "*"
57
+ hour = sched.attributes["Hour"] || "*"
58
+ mday = sched.attributes["DayOfMonth"] || "*"
59
+ month = sched.attributes["Month"] || "*"
60
+ wday = sched.attributes["DayOfWeek"] || "*"
61
+ cmd = (sched.elements["Command"].cdatas[0]).value().strip()
62
+ contents << minute + "\t" + hour + "\t" + mday + "\t" + month + "\t" + wday + "\t" + cmd + "\n"
63
+ }
64
+ return(contents.join(""))
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,51 @@
1
+ module Promotion
2
+ module Generator
3
+ module Newsyslog
4
+
5
+ # Writes the Newsyslog configuration
6
+ def self.generate(specs)
7
+ sym = "Newsyslog"
8
+ begin
9
+ originalContents = Promotion::Generator::original_contents_for(sym)
10
+ newContents = originalContents + Marker + contents(specs)
11
+ Promotion::Generator::write_file_for(sym, newContents)
12
+ rescue => e
13
+ $log.error("Error occurred while generating #{sym}\n#{e.message}" + e.backtrace.join("\n"))
14
+ exit 1
15
+ end
16
+ end
17
+
18
+ # Generates the contents for /etc/newsyslog.conf, which controls rolling and retention of logs
19
+ def self.contents(specs)
20
+ contents = []
21
+ contents << "# This section of the file should not be edited\n"
22
+ contents << "# It was generated by the promotion application and will be overwritten\n"
23
+ contents << "# when the next promotion occurs.\n"
24
+ contents << "# The previous section will be preserved\n\n"
25
+ contents << "# Filename Owner:Group Mode Count Size When Flags\n"
26
+ specs.each { |spec|
27
+ spec.elements.each("/Specification/Newsyslog") { |nsl|
28
+ contents << "%-40s" % nsl.text()
29
+ owner = nsl.attributes["Owner"]
30
+ group = nsl.attributes["Group"]
31
+ if owner.nil? or group.nil?
32
+ og = ""
33
+ else
34
+ og = owner + ":" + group
35
+ end
36
+ contents << "%-20s" % og
37
+ contents << "%-7s" % (nsl.attributes["Mode"] || "0640")
38
+ contents << "%-7s" % (nsl.attributes["Count"] || "*")
39
+ contents << "%-7s" % (nsl.attributes["Size"] || "*")
40
+ contents << "%-9s" % (nsl.attributes["When"] || "*")
41
+ contents << "Z" if (nsl.attributes["Zip"] || "true") == "true"
42
+ contents << "B" if (nsl.attributes["Binary"] || "false") == "true"
43
+ contents << "\n"
44
+ }
45
+ }
46
+ return(contents.join(""))
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ module Promotion
2
+ module Generator
3
+ module Profile
4
+
5
+ # Writes the system profile
6
+ def self.generate(specs)
7
+ sym = "Profile"
8
+ begin
9
+ originalContents = Promotion::Generator::original_contents_for(sym)
10
+ newContents = originalContents + Marker + contents(specs)
11
+ Promotion::Generator::write_file_for(sym, newContents)
12
+ rescue => e
13
+ $log.error("Error occurred while generating #{sym}\n#{e.message}" + e.backtrace.join("\n"))
14
+ exit 1
15
+ end
16
+ end
17
+
18
+ # Generates the contents for /etc/profile, containing environment variables and aliases
19
+ def self.contents(specs)
20
+ contents = []
21
+ contents << "# This section of the file should not be edited\n"
22
+ contents << "# It was generated by the promotion application and will be overwritten\n"
23
+ contents << "# when the next promotion occurs.\n"
24
+ contents << "# The previous section will be preserved\n"
25
+ specs.each { |spec|
26
+ spec.elements.each("/Specification/Environment") { |env|
27
+ env.elements.each("Variable") { |var|
28
+ t = var.cdatas.length > 0 ? var.cdatas[0].to_s() : var.text()
29
+ contents << "export #{var.attributes["Name"]}=\"#{t}\" \n"
30
+ }
31
+ env.elements.each("Alias") { |ali|
32
+ contents << "# #{ali.attributes["Comment"]}\n" if ali.attributes["Comment"]
33
+ t = ali.cdatas.length > 0 ? ali.cdatas[0].to_s() : ali.text()
34
+ contents << "alias #{ali.attributes["Name"]}='#{t}' \n"
35
+ }
36
+ }
37
+ }
38
+ return(contents.join(""))
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,48 @@
1
+ module Promotion
2
+ module Generator
3
+ module Rcconf
4
+
5
+ # Writes the system file /etc/rc.conf.local
6
+ def self.generate(specs)
7
+ sym = "Rc_conf"
8
+ begin
9
+ originalContents = Promotion::Generator::original_contents_for(sym)
10
+ newContents = originalContents + Marker + contents(specs)
11
+ Promotion::Generator::write_file_for(sym, newContents)
12
+ rescue => e
13
+ $log.error("Error occurred while generating #{sym}\n#{e.message}" + e.backtrace.join("\n"))
14
+ exit 1
15
+ end
16
+ end
17
+
18
+ # Generates the contents for /etc/rc.conf.local, containing instructions for running daemons
19
+ def self.contents(specs)
20
+ contents = []
21
+ contents << "# This section of the file should not be edited\n"
22
+ contents << "# It was generated by the promotion application and will be overwritten\n"
23
+ contents << "# when the next promotion occurs.\n"
24
+ contents << "# The previous section will be preserved\n"
25
+ contents << "# ---------------------------\n"
26
+ contents << "# generated application flags\n"
27
+ daemonSpecs = specs.reject {|s| s.elements["/Specification/Daemon"].nil? }
28
+ daemonSpecs.sort!() { |a, b|
29
+ ap = a.elements["/Specification/Daemon"].attributes["Priority"].to_i || 10
30
+ bp = b.elements["/Specification/Daemon"].attributes["Priority"].to_i || 10
31
+ ap <=> bp
32
+ }
33
+ pkgScripts = []
34
+ daemonSpecs.each { |spec|
35
+ name = spec.attributes["Name"]
36
+ flags = spec.elements["/Specification/Daemon"].attributes["Flags"]
37
+ contents << "#{name}_flags=\"#{flags}\" \n"
38
+ pkgScripts << name
39
+ }
40
+ contents << "# rc.d(8) packages scripts\n"
41
+ contents << "# started in the specified order and stopped in reverse order\n"
42
+ contents << "pkg_scripts=\"#{pkgScripts.join(" ")}\" \n"
43
+ return(contents.join(""))
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,55 @@
1
+ module Promotion
2
+ module Generator
3
+ module Sudoers
4
+
5
+ # Writes the sudoers file after testing it with visudo
6
+ def self.generate(specs)
7
+ sym = "Sudoers"
8
+ begin
9
+ originalContents = Promotion::Generator::original_contents_for(sym)
10
+ newContents = originalContents + Marker + contents(specs)
11
+ tempFilename = Promotion::Generator::write_file_for(sym, newContents, true)
12
+ $log.info("Checking temporary sudoers written to #{tempFilename}.")
13
+ visudoResults = `#{Files::Visudo} -c -f #{tempFilename}`
14
+ if visudoResults =~ /parsed OK/
15
+ $log.info("visudo confirms that sudoers syntax is correct.")
16
+ else
17
+ $log.error(visudoResults)
18
+ raise
19
+ end
20
+ Promotion::Generator::write_file_for("Sudoers", newContents)
21
+ FileUtils.rm_f(tempFilename)
22
+ rescue => e
23
+ $log.error("Error occurred while generating sudoers\n#{e.message}" + e.backtrace.join("\n"))
24
+ exit 1
25
+ end
26
+ end
27
+
28
+ # Generates the contents for /etc/sudoers, containing environment variables and aliases
29
+ def self.contents(specs)
30
+ contents = []
31
+ contents << "# This section of the file should not be edited\n"
32
+ contents << "# It was generated by the promotion application and will be overwritten\n"
33
+ contents << "# when the next promotion occurs.\n"
34
+ contents << "# The previous section will be preserved\n\n"
35
+ contents << "Defaults timestamp_timeout=55\n\n"
36
+ contents << "root ALL = (ALL) ALL \n"
37
+ contents << "# people in group wheel may run all commands \n"
38
+ contents << "%wheel ALL = (ALL) ALL \n\n"
39
+ contents << "# Generated user privilege specifications \n"
40
+ specs.each { |spec|
41
+ spec.elements.each("/Specification/Sudoers/UserPrivilege") { |priv|
42
+ contents << "%-16s" % priv.attributes["User"]
43
+ contents << " ALL = "
44
+ contents << "(#{priv.attributes["Runas"]}) " if priv.attributes["Runas"]
45
+ pwd = (priv.attributes["Password"] || "false").downcase() == "true"
46
+ contents << (pwd ? " " : "NOPASSWD: ")
47
+ contents << "#{priv.text().strip()} \n"
48
+ }
49
+ }
50
+ return(contents.join(""))
51
+ end
52
+
53
+ end
54
+ end
55
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: promotion
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
- - 0
10
- version: 1.3.0
9
+ - 1
10
+ version: 1.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Richard Kernahan
@@ -65,10 +65,11 @@ files:
65
65
  - lib/promotion/enforcer.rb
66
66
  - lib/promotion/evolver.rb
67
67
  - lib/promotion/generator.rb
68
- - lib/promotion/erb/crontab.erb
69
- - lib/promotion/erb/profile.erb
70
- - lib/promotion/erb/rc.conf.local.erb
71
- - lib/promotion/erb/sudoers.erb
68
+ - lib/promotion/generator/crontab.rb
69
+ - lib/promotion/generator/newsyslog.rb
70
+ - lib/promotion/generator/profile.rb
71
+ - lib/promotion/generator/rcconf.rb
72
+ - lib/promotion/generator/sudoers.rb
72
73
  - .yardopts
73
74
  - promotion.xsd
74
75
  - CHANGELOG
@@ -1,19 +0,0 @@
1
- #
2
- # /var/cron/tabs/<%= user %> - <%= user %>'s crontab
3
- #
4
- #minute hour mday month wday command
5
- #
6
- <% crontablist.each do |sched| %>
7
- <% if sched.attributes["Comment"] %>
8
- #______________________________
9
- # <%= sched.attributes["Comment"] %>
10
- <% end %>
11
- <% minute = sched.attributes["Minute"] || "*" %>
12
- <% hour = sched.attributes["Hour"] || "*" %>
13
- <% mday = sched.attributes["DayOfMonth"] || "*" %>
14
- <% month = sched.attributes["Month"] || "*" %>
15
- <% wday = sched.attributes["DayOfWeek"] || "*" %>
16
- <% cmd = (sched.elements["Command"].cdatas[0]).value().strip() %>
17
- <%= minute + "\t" + hour + "\t" + mday + "\t" + month + "\t" + wday + "\t" + cmd %>
18
-
19
- <% end %>
@@ -1,17 +0,0 @@
1
- # This section of the file should not be edited
2
- # It was generated by the promotion application and will be overwritten
3
- # when the next promotion occurs.
4
- # The previous section will be preserved
5
- <% @specs.each do |spec|
6
- spec.elements.each("/Specification/Environment") do |env|
7
- env.elements.each("Variable") do |var|
8
- t = var.cdatas.length > 0 ? var.cdatas[0].to_s() : var.text() %>
9
- export <%= var.attributes["Name"] %>="<%= t %>"<% end %>
10
- <% env.elements.each("Alias") do |ali|
11
- t = ali.cdatas.length > 0 ? ali.cdatas[0].to_s() : ali.text()
12
- %><% if ali.attributes["Comment"] %><%= "\n# "+ali.attributes["Comment"]
13
- %><% end %>
14
- alias <%= ali.attributes["Name"] %>='<%= t %>' <%
15
- end
16
- end
17
- end %>
@@ -1,20 +0,0 @@
1
- # This section of the file is generated by the promotion application
2
- # DO NOT EDIT THIS SECTION - your changes will be lost
3
- # You may edit the section before the promotion marker
4
- #______________________________
5
- # generated application flags
6
- <% daemonSpecs = @specs.reject {|s| s.elements["/Specification/Daemon"].nil? } %>
7
- <% daemonSpecs.sort!() do |a, b| %>
8
- <% ap = a.elements["/Specification/Daemon"].attributes["Priority"].to_i || 10 %>
9
- <% bp = b.elements["/Specification/Daemon"].attributes["Priority"].to_i || 10 %>
10
- <% ap <=> bp %>
11
- <% end %>
12
- <% pkgScripts = [] %>
13
- <% daemonSpecs.each do |spec| %>
14
- <%= spec.attributes["Name"] %>_flags="<%= spec.elements["/Specification/Daemon"].attributes["Flags"] %>"
15
- <% pkgScripts << spec.attributes["Name"] %>
16
- <% end %>
17
-
18
- # rc.d(8) packages scripts
19
- # started in the specified order and stopped in reverse order
20
- pkg_scripts="<%= pkgScripts.join(" ") %>"
@@ -1,22 +0,0 @@
1
- # This section of the file should not be edited, even with visudo
2
- # It was generated by the promotion application and will be overwritten
3
- # when the next promotion occurs.
4
- # The previous section will be preserved
5
-
6
- Defaults timestamp_timeout=55
7
-
8
- root ALL = (ALL) ALL
9
- # people in group wheel may run all commands
10
- %wheel ALL = (ALL) ALL
11
-
12
- # Generated user privilege specifications
13
- <% @specs.each do |spec| %>
14
- <% spec.elements.each("/Specification/Sudoers/UserPrivilege") do |priv| %>
15
- <%= sprintf('%-16s', priv.attributes["User"]) %>
16
- <%= " ALL = " %>
17
- <% if priv.attributes["Runas"] %>(<%= priv.attributes["Runas"] %>) <% end %>
18
- <%= (priv.attributes["Password"] || "").downcase() == "true" ? " " : "NOPASSWD: " %>
19
- <%= priv.text().strip() %>
20
-
21
- <% end %>
22
- <% end %>