Skip to content
Browse files

merged from dev for release v1.0

  • Loading branch information...
1 parent d39c763 commit 75d8de593d57689ab8808bbb2111f75a2bcb584c @kharmajbird committed Nov 22, 2012
Showing with 478 additions and 91 deletions.
  1. 0 Makefile
  2. +51 −70 README
  3. +175 −0 example.txt
  4. +252 −21 genpuppet.pl
View
0 Makefile
No changes.
View
121 README
@@ -1,70 +1,51 @@
-genpuppet is a program to automatically generate puppet manifests based on
-a series of user inputs. Think of a kernel "make config" for puppet.
-
-
-
-== command line user input ==
-
-# ./genpuppet.pl
-Name of manifest? init.pp
-Name of class? myclass
-Top level require? first
-Top level require?
-Top level include? incl1
-Top level include? incl2
-Top level include?
-Use class nullmailer? [no] yes
-adminaddr => foo@bar.com
-remoterelay => foor@mail.com
-Use exec set-semaphore? [no]
-Package name? pack1
-ensure => latest
-before => Exec['do-pkgstuff']
-before => File['/etc/foo']
-before =>
-require => Package['sub']
-require =>
-Package name? pack2
-ensure => installed
-before =>
-require => File['alpha']
-require => Class['ntp']
-require =>
-Package name?
-
-
-== generated manuscript ==
-
-# cat init.pp
-class myclass {
- require first
-
- include incl1
- include incl2
-
- class { 'nullmailer':
- adminaddr => 'foo@bar.com',
- remoterelay => 'foor@mail.com',
- }
-
- package { 'pack1':
- ensure => latest,
- before => [
- Exec['do-pkgstuff'],
- File['/etc/foo'],
- ],
- require => [
- Package['sub'],
- ],
- }
-
- package { 'pack2':
- ensure => installed,
- require => [
- Package['sub'],
- File['alpha'],
- Class['ntp'],
- ],
- }
-
-}
+genpuppet is a script to automatically generate a puppet manifest based on
+a series of user inputs. Think of it as a kernel "make config" for puppet.
+
+With genpuppet, one can quickly create a custom manifest without worrying
+so much about syntax and spacing.
+
+Save the time you would normally spend writing a manifest from scratch and
+use that time to debug that circular dependency you've been putting off ;)
+
+
+
+GENPUPPET
+
+Features:
+
+* Creates resource "stanzas" for package, service, file, and exec
+* Prompts for the most common metaparameters of those resources
+* Manages commas and bracket/brace placement for you
+* Generates puppet code that is immediately useable
+
+
+Shortcomings:
+
+* Single quotes are used exclusively.
+
+ If you need to quote a variable, edit the generated manifest and replace
+ the single quotes around your variable with double quotes.
+
+
+* Many resources are still unsupported.
+
+ Only the basic resources are currently handled, such as the ones you
+ might find on a cheat sheet. Nothing prevents me or anyone else from
+ extending genpuppet to handle any other resource type except...
+
+
+* The code is nothing to write home about.
+
+ It gets the job done, that's it. Perl enthusiasts may cringe at some
+ of my barbaric techniques, and there is a lot of near-duplication of
+ code. I'm sure there is a better, more slick way of accomplishing this
+ by using parameters, but it already works for me and it didn't take
+ long to write. If I find I want to add another resource, however, I
+ will be looking at and taking suggestions for how to make the script
+ more efficient.
+
+
+I encourage the puppet community to contribute their suggestions and
+changes for this project. Genpuppet has the potential to become a very useful
+and robust tool within a puppetmaster's kit. The basics are already here,
+but there is a lot more that can be done to make it a better tool.
View
175 example.txt
@@ -0,0 +1,175 @@
+This example is a transcript of a single run of genpuppet.
+
+Each line is a question and an answer separated by either a "?" or "=>".
+See how it simply prompts for user input, and stores the results in
+a hash of hashes similar to:
+
+%{ $resource{'package'}{$package_name}{'metaparameter'} }
+
+It doesn't matter what you enter for each prompt, but if you want working
+puppet code to be generated, you may wish to enter something syntactically
+correct :)
+
+
+
+== command line user input ==
+
+# ./genpuppet.pl
+Name of manifest? init.pp
+Name of class? myclass
+Top level require? first
+Top level require?
+Top level include? incl1
+Top level include? incl2
+Top level include?
+Use class nullmailer? [no] yes
+adminaddr => foo@bar.com
+remoterelay => foor@mail.com
+Use exec set-semaphore? [no]
+Package name? pack1
+ensure => latest
+before => Exec['do-pkgstuff']
+before => File['/etc/foo']
+before =>
+require => Package['sub']
+require =>
+Package name? pack2
+ensure => installed
+before =>
+require => File['alpha']
+require => Class['ntp']
+require =>
+Package name?
+Service name? ntp
+ensure => running
+before =>
+require => puppet
+require => Service['puppetmaster']
+require =>
+Service name? cron
+ensure => stopped
+before => ntpservice
+before => Exec['something']
+before =>
+require => kitchen
+require => sink
+require =>
+Service name?
+File path? /etc/sudoers
+ensure => file
+owner => root
+group => root
+mode => 0400
+source => our source path
+content =>
+before => Service['ntp']
+before =>
+require =>
+File path?
+Exec name? apt-update
+command => apt-get update
+logoutput => yes
+onlyif => test -f /tmp/flag
+unless =>
+creates =>
+before =>
+require => Service['ntp']
+require => another service
+require =>
+Exec name? apt-upgrade
+command => apt-get upgrade
+logoutput => no
+onlyif =>
+unless =>
+creates => /tmp/foo
+before => one run
+before => second run
+before =>
+require =>
+Exec name?
+
+
+
+== generated manuscript ==
+
+# cat init.pp
+class myclass {
+ require first
+
+ include incl1
+ include incl2
+
+ class { 'nullmailer':
+ adminaddr => 'foo@bar.com',
+ remoterelay => 'foor@mail.com',
+ }
+
+ package { 'pack1':
+ ensure => latest,
+ before => [
+ Exec['do-pkgstuff'],
+ File['/etc/foo'],
+ ],
+ require => [
+ Package['sub'],
+ ],
+ }
+
+ package { 'pack2':
+ ensure => installed,
+ require => [
+ Package['sub'],
+ File['alpha'],
+ Class['ntp'],
+ ],
+ }
+
+ service { 'cron':
+ ensure => stopped,
+ before => [
+ ntpservice,
+ Exec['something'],
+ ],
+ require => [
+ kitchen,
+ sink,
+ ],
+ }
+ service { 'ntp':
+ ensure => running,
+ require => [
+ puppet,
+ Service['puppetmaster'],
+ ],
+ }
+
+ file { '/etc/sudoers':
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0400',
+ source => 'our source path',
+ before => [
+ Service['ntp'],
+ ],
+ }
+
+ exec { 'apt-upgrade':
+ command => 'apt-get upgrade',
+ logoutput => 'no',
+ creates => '/tmp/foo',
+ before => [
+ one run,
+ second run,
+ ],
+ }
+ exec { 'apt-update':
+ command => 'apt-get update',
+ logoutput => 'yes',
+ onlyif => 'test -f /tmp/flag',
+ require => [
+ Service['ntp'],
+ another service,
+ ],
+ }
+}
View
273 genpuppet.pl
@@ -24,8 +24,13 @@
do_toplevel();
get_packages();
write_packages();
+get_services();
+write_services();
get_files();
write_files();
+get_execs();
+write_execs();
+write_swatch();
# write end class
#
@@ -53,7 +58,7 @@ sub do_toplevel {
printf FP " require $inc\n";
}
- printf FP "\n";
+ if (@requires) { printf FP "\n"; }
print "Top level include? ";
@@ -69,7 +74,7 @@ sub do_toplevel {
printf FP " include $inc\n";
}
- printf FP "\n";
+ if (@includes) { printf FP "\n"; }
print "Use class nullmailer? [no] ";
@@ -86,22 +91,18 @@ sub do_toplevel {
printf FP " }\n\n";
}
-
print "Use exec set-semaphore? [no] ";
chomp ($var = <>);
-
- # need to handle this just before the end of the class"
- #
if ($var) { $semaphore=1; }
}
+# end do_toplevel()
#
# get all package resources and their metaparameters
#
sub get_packages {
- my $pname, $ensure;
- my $var;
+ my $pname, $var;
print "Package name? ";
chomp ($pname = <>);
@@ -110,11 +111,7 @@ sub get_packages {
my @before = (), @require = ();
print "ensure => ";
- chomp ($var = <>);
-
- if ($var) {
- $resources{'package'}->{$pname}->{'ensure'} = $var;
- }
+ chomp ($resources{'package'}->{$pname}->{'ensure'} = <>);
print "before => ";
chomp ($var = <>);
@@ -144,7 +141,7 @@ sub get_packages {
chomp ($pname = <>);
}
}
-
+# end get_packages()
#
@@ -182,14 +179,101 @@ sub write_packages {
}
printf FP " }\n";
}
+ printf FP "\n\n";
+}
+# end write_packages()
+
+
+#
+#
+#
+sub get_services {
+ my $sname, $var;
+
+ print "Service name? ";
+ chomp ($sname = <>);
+
+ while ($sname) {
+ my @before = (), @require = ();
+
+ print "ensure => ";
+ chomp ($resources{'service'}->{$sname}->{'ensure'} = <>);
+
+ print "before => ";
+ chomp ($var = <>);
+ while ($var) {
+ push (@before, $var);
+
+ print "before => ";
+ chomp ($var = <>);
+ }
+ if (@before) {
+ @{ $resources{'service'}->{$sname}->{'before'} } = @before;
+ }
+
+ print "require => ";
+ chomp ($var = <>);
+ while ($var) {
+ push (@require, $var);
+
+ print "require => ";
+ chomp ($var = <>);
+ }
+ if (@require) {
+ @{ $resources{'service'}->{$sname}->{'require'} } = @require;
+ }
+
+ print "Service name? ";
+ chomp ($sname = <>);
+ }
+}
+# end get_services()
+
+#
+# write service stanzas
+#
+sub write_services {
+ foreach my $var (reverse keys %{ $resources{'service'} }) {
+ printf FP " service { '$var':\n";
+ printf FP " ensure => $resources{'service'}{$var}{'ensure'},\n";
+
+ # do before =>
+ #
+ if ($resources{'service'}{$var}{'before'}) {
+ my @ary = @{ $resources{'service'}{$var}{'before'} };
+
+ printf FP " before => [\n";
+ while (@ary) {
+ my $bf = shift (@ary);
+ printf FP " $bf,\n";
+ }
+ printf FP " ],\n";
+ }
+
+ # do require =>
+ #
+ if ($resources{'service'}{$var}{'require'}) {
+ my @ary = @{ $resources{'service'}{$var}{'require'} };
+
+ printf FP " require => [\n";
+ while (@ary) {
+ my $bf = shift (@ary);
+ printf FP " $bf,\n";
+ }
+ printf FP " ],\n";
+ }
+ printf FP " }\n";
+ }
+ printf FP "\n\n";
}
+# end write_services()
#
# get all file resources and their metaparameters
#
sub get_files {
- my $fname, $ensure;
+ my $fname;
my $var;
print "File path? ";
@@ -244,19 +328,40 @@ sub get_files {
chomp ($fname = <>);
}
}
+# end get_files()
+
#
# write file stanzas
#
sub write_files {
foreach my $var (reverse keys %{ $resources{'file'} }) {
printf FP " file { '$var':\n";
- printf FP " ensure => '$resources{'file'}{$var}{'ensure'}',\n";
- printf FP " owner => '$resources{'file'}{$var}{'owner'}',\n";
- printf FP " group => '$resources{'file'}{$var}{'group'}',\n";
- printf FP " mode => '$resources{'file'}{$var}{'mode'}',\n";
- printf FP " source => '$resources{'file'}{$var}{'source'}',\n";
- printf FP " content => $resources{'file'}{$var}{'content'},\n";
+
+ if ($resources{'file'}{$var}{'ensure'}) {
+ printf FP
+ " ensure => '$resources{'file'}{$var}{'ensure'}',\n";
+ }
+ if ($resources{'file'}{$var}{'owner'}) {
+ printf FP
+ " owner => '$resources{'file'}{$var}{'owner'}',\n";
+ }
+ if ($resources{'file'}{$var}{'group'}) {
+ printf FP
+ " group => '$resources{'file'}{$var}{'group'}',\n";
+ }
+ if ($resources{'file'}{$var}{'mode'}) {
+ printf FP
+ " mode => '$resources{'file'}{$var}{'mode'}',\n";
+ }
+ if ($resources{'file'}{$var}{'source'}) {
+ printf FP
+ " source => '$resources{'file'}{$var}{'source'}',\n";
+ }
+ if ($resources{'file'}{$var}{'content'}) {
+ printf FP
+ " content => $resources{'file'}{$var}{'content'},\n";
+ }
# do before =>
#
@@ -285,4 +390,130 @@ sub write_files {
}
printf FP " }\n";
}
+ printf FP "\n\n";
+}
+# end write_files()
+
+#
+#
+#
+sub get_execs {
+ my $exec, $var;
+
+ print "Exec name? ";
+ chomp ($exec = <>);
+
+ while ($exec) {
+ my @before = (), @require = ();
+
+ print "command => ";
+ chomp ($resources{'exec'}->{$exec}->{'command'} = <>);
+
+ print "logoutput => ";
+ chomp ($resources{'exec'}->{$exec}->{'logoutput'} = <>);
+
+ print "onlyif => ";
+ chomp ($resources{'exec'}->{$exec}->{'onlyif'} = <>);
+
+ print "unless => ";
+ chomp ($resources{'exec'}->{$exec}->{'unless'} = <>);
+
+ print "creates => ";
+ chomp ($resources{'exec'}->{$exec}->{'creates'} = <>);
+
+ print "before => ";
+ chomp ($var = <>);
+ while ($var) {
+ push (@before, $var);
+
+ print "before => ";
+ chomp ($var = <>);
+ }
+ if (@before) {
+ @{ $resources{'exec'}->{$exec}->{'before'} } = @before;
+ }
+
+ print "require => ";
+ chomp ($var = <>);
+ while ($var) {
+ push (@require, $var);
+
+ print "require => ";
+ chomp ($var = <>);
+ }
+ if (@require) {
+ @{ $resources{'exec'}->{$exec}->{'require'} } = @require;
+ }
+
+ print "Exec name? ";
+ chomp ($exec = <>);
+ }
+}
+# end get_execs()
+
+
+#
+#
+#
+sub write_execs {
+ foreach my $var (reverse keys %{ $resources{'exec'} }) {
+ printf FP " exec { '$var':\n";
+
+ if ($resources{'exec'}{$var}{'command'}) {
+ printf FP
+ " command => '$resources{'exec'}{$var}{'command'}',\n";
+ }
+ if ($resources{'exec'}{$var}{'logoutput'}) {
+ printf FP
+ " logoutput => '$resources{'exec'}{$var}{'logoutput'}',\n";
+ }
+ if ($resources{'exec'}{$var}{'onlyif'}) {
+ printf FP
+ " onlyif => '$resources{'exec'}{$var}{'onlyif'}',\n";
+ }
+ if ($resources{'exec'}{$var}{'unless'}) {
+ printf FP
+ " unless => '$resources{'exec'}{$var}{'unless'}',\n";
+ }
+ if ($resources{'exec'}{$var}{'creates'}) {
+ printf FP
+ " creates => '$resources{'exec'}{$var}{'creates'}',\n";
+ }
+
+ # do before =>
+ #
+ if ($resources{'exec'}{$var}{'before'}) {
+ my @ary = @{ $resources{'exec'}{$var}{'before'} };
+
+ printf FP " before => [\n";
+ while (@ary) {
+ my $bf = shift (@ary);
+ printf FP " $bf,\n";
+ }
+ printf FP " ],\n";
+ }
+
+ # do require =>
+ #
+ if ($resources{'exec'}{$var}{'require'}) {
+ my @ary = @{ $resources{'exec'}{$var}{'require'} };
+
+ printf FP " require => [\n";
+ while (@ary) {
+ my $bf = shift (@ary);
+ printf FP " $bf,\n";
+ }
+ printf FP " ],\n";
+ }
+ printf FP " }\n";
+ }
+ printf FP "\n\n";
+}
+# end write_execs()
+
+#
+#
+#
+sub write_swatch {
+ return if ($semaphore);
}

0 comments on commit 75d8de5

Please sign in to comment.
Something went wrong with that request. Please try again.