puppi 0.0.1alpha

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ require 'autotest'
2
+
3
+ Autotest.add_hook :initialize do |at|
4
+ at.clear_mappings
5
+ # watch out for Ruby bug (1.8.6): %r(/) != /\//
6
+ at.add_mapping(%r%^spec/.*_spec\.rb$%) { |filename, _|
7
+ filename
8
+ }
9
+ at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m|
10
+ ["spec/#{m[1]}_spec.rb"]
11
+ }
12
+ at.add_mapping(%r%^spec/(spec_helper|shared/.*)\.rb$%) {
13
+ at.files_matching %r%^spec/.*_spec\.rb$%
14
+ }
15
+ end
16
+
17
+ class RspecCommandError < StandardError; end
18
+
19
+ class Autotest::Rspec < Autotest
20
+
21
+ SPEC_PROGRAM = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec'))
22
+
23
+ def initialize
24
+ super
25
+ self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n\n?(.*?(\n\n\(.*?)?)\n\n/m
26
+ self.completed_re = /\n(?:\e\[\d*m)?\d* examples?/m
27
+ end
28
+
29
+ def consolidate_failures(failed)
30
+ filters = new_hash_of_arrays
31
+ failed.each do |spec, trace|
32
+ if trace =~ /\n(\.\/)?(.*spec\.rb):[\d]+:/
33
+ filters[$2] << spec
34
+ end
35
+ end
36
+ return filters
37
+ end
38
+
39
+ def make_test_cmd(files_to_test)
40
+ files_to_test.empty? ? '' :
41
+ "#{ruby} #{SPEC_PROGRAM} --autospec #{normalize(files_to_test).keys.flatten.join(' ')} #{add_options_if_present}"
42
+ end
43
+
44
+ def normalize(files_to_test)
45
+ files_to_test.keys.inject({}) do |result, filename|
46
+ result[File.expand_path(filename)] = []
47
+ result
48
+ end
49
+ end
50
+
51
+ def add_options_if_present # :nodoc:
52
+ File.exist?("spec/spec.opts") ? "-O #{File.join('spec','spec.opts')} " : ""
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+ coverage/
3
+ *.gem
4
+ .bundle
5
+ Gemfile.lock
6
+ pkg/*
7
+ tmp/
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode # JRuby in 1.8 mode
7
+ - jruby-19mode # JRuby in 1.9 mode
8
+ - rbx-18mode
9
+ - rbx-19mode
10
+ # uncomment this line if your project needs to run something other than `rake`:
11
+ script: RUN_ENV=TEST bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'mail'
4
+ gem 'rake'
5
+
6
+ group :test do
7
+ gem 'autotest'
8
+ gem 'rspec'
9
+ gem 'fakefs'
10
+ gem 'simplecov'
11
+ end
12
+
13
+ # Specify your gem's dependencies in puppi-ruby.gemspec
14
+ gemspec
@@ -0,0 +1,51 @@
1
+ = Puppi on Ruby
2
+
3
+ This is an experimental version of Puppi made in Ruby
4
+ It's supposed to replace the existing puppi command written in bash.
5
+
6
+
7
+ == README (DRIVEN DEVELOPMENT)
8
+
9
+ puppi <action> <project_name> [ -options ]
10
+
11
+ The puppi command has these possibile actions:
12
+
13
+ * [ puppi init project_name ] : First time initialization of the defined project
14
+
15
+ * [ puppi deploy project_name ] : Deploys the defined project
16
+
17
+ * [ puppi rollback project_name ] : Rollback to a previous deploy state
18
+
19
+ * [ puppi check ] : Runs project specific and host wide checks
20
+
21
+ * [ puppi log ] : Tails system wide or project specific logs
22
+
23
+ * [ puppi info topic_name ] : Show system information (for all or only the specified topic)
24
+
25
+ * [ puppi todo ] : Show things to do (or done) manually on the system
26
+
27
+ And these options:
28
+
29
+ * -f - Force puppi commands execution flow also on CRITICAL errors
30
+
31
+ * -i - Interactively ask confirmation for every step
32
+
33
+ * -t - Test mode. Just show the commands that should be executed
34
+
35
+ * -d <yes|full> - Debug mode. Show debug of what is done.
36
+
37
+ * -r <yes|no|fail> - Enable reporting: yes/no/only on failures. Default depends on action
38
+
39
+ * -s <yes|no|fail> - Show output: yes/no/only for failures. Default: yes
40
+
41
+ * -g <pattern> - Grep command output with the selected pattern
42
+
43
+ * -o "parameter=value parameter2=value2" - Set manual options to override defaults
44
+
45
+
46
+ === Files and directories
47
+
48
+ * /etc/puppi/data (datadir) contains one yaml file for each Puppet class or defines that uses the puppi::ze define.
49
+ This yaml contains all the variables provided by the class / define and has this naming layout:
50
+ helper_module.yaml. Where helper is the name of the helper file to use to manage the variables provided in the file and module is the name of the module or class or define that has created the yaml via puppi::ze
51
+ * /etc/puppi/helpers contains the helpers file (created by puppi::helper): a Yaml that describes, for each puppi action, what commands to run and the names of the variables to use (as named in the /etc/puppi/data/helper_module.yaml files)
@@ -0,0 +1,4 @@
1
+ require "rspec/core/rake_task"
2
+ require "bundler/gem_tasks"
3
+
4
+ RSpec::Core::RakeTask.new
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require 'puppi'
5
+ Puppi::initial_checks
6
+
7
+ begin
8
+ options = Hash.new
9
+ OptionParser.new do |opts|
10
+ opts.banner = "Usage: " + File.basename($0) + " [options] ..."
11
+
12
+ options[:action] = false
13
+ opts.on( "-a", "--action action", String, "action to perform" ) do |action|
14
+ options[:action] = action
15
+ end
16
+ options[:puppi_module] = nil
17
+ opts.on( "-m", "--module module", String, "module name to act on (Optional)" ) do |puppi_module|
18
+ options[:puppi_module] = puppi_module
19
+ end
20
+ options[:notification] = Array.new
21
+ opts.on( "-n", "--notification notification1,notification2", Array, "notification(s) methods (Optional)" ) do |notification|
22
+ options[:notification] = notification
23
+ end
24
+ opts.on_tail("-h", "--help", "Show this message") do
25
+ puts opts
26
+ end
27
+ end.parse!
28
+ rescue OptionParser::MissingArgument => e
29
+ warn "You can't specify an option without any argumento ("+e.to_s+")"
30
+ exit 1
31
+ end
32
+
33
+ if options.values.uniq == [false]
34
+ warn "Use -h, --help for usage."
35
+ exit 1
36
+ end
37
+
38
+ if options[:action] == false
39
+ warn "You MUST specify an action"
40
+ warn "Use -h, --help for usage."
41
+ exit 1
42
+ end
43
+
44
+ output = Puppi::Action.new(options).output
45
+ Puppi::Notification.new(options[:notification], output)
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: openssh
3
+ config_file_mode: "0644"
4
+ puppi_helper: standard
5
+ monitor_tool: puppi nagios munin
6
+ manage_file: present
7
+ manage_monitor: true
8
+ source_dir_purge: false
9
+ bool_debug: false
10
+ title: openssh
11
+ data_dir: /etc/ssh
12
+ config_file_init: /etc/sysconfig/sshd
13
+ firewall: false
14
+ source_dir: ""
15
+ caller_module_name: openssh
16
+ port: "22"
17
+ log_file: /var/log/messages
18
+ service: sshd
19
+ firewall_tool: ""
20
+ bool_firewall: false
21
+ protocol: tcp
22
+ config_file_owner: root
23
+ process: sshd
24
+ puppi: "true"
25
+ monitor_target: 0.0.0.0
26
+ manage_file_replace: true
27
+ config_file_group: root
28
+ process_user: root
29
+ firewall_src: 0.0.0.0/0
30
+ bool_absent: false
31
+ manage_package: present
32
+ service_status: true
33
+ package: openssh-server
34
+ monitor: "yes"
35
+ disableboot: false
36
+ template: ""
37
+ manage_service_ensure: running
38
+ manage_firewall: true
39
+ config_file: /etc/ssh/sshd_config
40
+ config_dir: /etc/ssh
41
+ bool_disableboot: false
42
+ bool_monitor: true
43
+ bool_audit_only: false
44
+ module_name: openssh
45
+ process_args: ""
46
+ debug: "no"
47
+ disable: false
48
+ bool_disable: false
49
+ bool_puppi: true
50
+ log_dir: /var/log
51
+ pid_file: /var/run/sshd.pid
52
+ audit_only: false
53
+ absent: false
54
+ source: ""
55
+ my_class: ""
56
+ manage_service_enable: true
57
+ firewall_dst: 10.42.20.10
58
+ options: ""
59
+ bool_source_dir_purge: false
@@ -0,0 +1,13 @@
1
+ ---
2
+ :info:
3
+ -
4
+ :command: "rpm -qi $package_name"
5
+ :description: "show package info"
6
+ -
7
+ :command: "service $service_name"
8
+ :description: "show service info"
9
+ :check:
10
+ -
11
+ :command: "chk_port $port"
12
+ :description: "checks port"
13
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'pry'
5
+ require File.dirname(__FILE__) + '/lib/puppi'
6
+
7
+ require 'puppi'
8
+
9
+ binding.pry
@@ -0,0 +1,34 @@
1
+ module Puppi
2
+ require 'fileutils'
3
+ require 'puppi/files/datafile'
4
+ require 'puppi/files/helper'
5
+ require 'puppi/files/notification'
6
+ require 'puppi/action'
7
+ require 'puppi/generate_sample_data'
8
+ require 'puppi/loader'
9
+ require 'puppi/notification'
10
+ require 'puppi/notifications/mail'
11
+ require 'puppi/notifications/stdout'
12
+ require 'puppi/version'
13
+ require 'yaml'
14
+
15
+ if ENV["RUN_ENV"] == "TEST"
16
+ @@puppidir = File.dirname(File.dirname(__FILE__))+"/tmp/config"
17
+ else
18
+ @@puppidir = "/etc/puppi"
19
+ end
20
+
21
+ class << self
22
+ def puppidir
23
+ @@puppidir
24
+ end
25
+
26
+ def initial_checks
27
+ directories = %w[ data helpers notifications ]
28
+ directories.each do |directory|
29
+ FileUtils.mkdir_p @@puppidir+'/'+directory
30
+ raise "Puppi::NoPuppiDir" unless File.directory?(puppidir+'/'+directory)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,50 @@
1
+ module Puppi
2
+ class Action
3
+ attr_reader :puppi_module, :output
4
+
5
+ def initialize (options)
6
+ @loader = Puppi::Loader.new
7
+ @actions = [ 'check', 'log', 'info' ]
8
+ if options[:puppi_module].nil?
9
+ @puppi_module = nil
10
+ else
11
+ @puppi_module = options[:puppi_module].to_s
12
+ end
13
+ if @actions.include? options[:action].to_s
14
+ execute options[:action].to_s
15
+ else
16
+ raise "No Action Found"
17
+ end
18
+ end
19
+
20
+ def execute action
21
+ @datafiles = @loader.load_all('data', @puppi_module)
22
+ @output = Array.new
23
+ @datafiles.each do |datafile|
24
+ @loaded_datafile = @loader.load_datafile(datafile)
25
+ datafile_helper = datafile.split("_")[0]
26
+ module_helper = datafile.split("_")[1]
27
+ @helper_commands = @loader.load_helperfile datafile_helper, action
28
+ return nil unless not @helper_commands.nil?
29
+ @helper_commands.each do |command|
30
+ @output << (run_command command, module_helper)
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+ def run_command command, module_helper
37
+ @running_command = prepare_command command.command
38
+ output = IO.popen(@running_command, :err => [:child, :out]) unless @running_command.nil?
39
+ output.nil? ? nil : output.read
40
+ end
41
+
42
+ def prepare_command command
43
+ begin
44
+ command % @loaded_datafile.variables
45
+ rescue KeyError
46
+ nil
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ module Puppi
2
+ module Files
3
+ class Datafile
4
+ attr_reader :variables
5
+
6
+ def initialize args = {}
7
+ @variables = args
8
+ @var = Hash.new
9
+ @variables.each_key do |key|
10
+ @var[key.to_sym] = @variables[key]
11
+ end
12
+ @variables = @var
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module Puppi
2
+ module Files
3
+ class Helper
4
+ attr_reader :command, :description
5
+
6
+ def initialize args = {}
7
+ @command = args[:command]
8
+ @description = args[:description]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Puppi
2
+ module Files
3
+ class Notification
4
+ attr_reader :variables
5
+
6
+ def initialize args = {}
7
+ @variables = args
8
+ @var = Hash.new
9
+ @variables.each_key do |key|
10
+ @var[key.to_sym] = @variables[key]
11
+ end
12
+ @variables = @var
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,45 @@
1
+ module Puppi
2
+ class GenerateSampleData
3
+ def initialize
4
+ end
5
+
6
+ def helpers
7
+ write_file '/helpers/standard.yml', '---
8
+ :info:
9
+ -
10
+ :command: echo "+ %{name} +"
11
+ :description: "info module name for tests"
12
+ :check:
13
+ -
14
+ :command: echo "| %{name} |"
15
+ :description: "check module name for tests"
16
+ -
17
+ :command: echo "| %{version} |"
18
+ :description: "check module version"'
19
+ end
20
+
21
+ def datafiles
22
+ write_file '/data/standard_openssh.yml', '---
23
+ name: openssh
24
+ version: 1.0'
25
+ write_file '/data/standard_hostname.yml', '---
26
+ name: hostname'
27
+ end
28
+
29
+ def notifications
30
+ write_file '/notifications/mail_user1.yml', '---
31
+ from: puppi@puppi.com
32
+ to: user1@mail.com
33
+ subject: \'[puppi] notification\''
34
+ write_file '/notifications/mail_user2.yml', '---
35
+ from: puppi@puppi.com
36
+ to: user2@mail.com
37
+ subject: \'[puppi] notification\''
38
+ end
39
+
40
+ private
41
+ def write_file file, string
42
+ File.open(Puppi::puppidir+file, 'w') {|f| f.write(string) }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,46 @@
1
+ module Puppi
2
+ class Loader
3
+
4
+ attr_reader :data, :datafiles, :helpers, :notifications
5
+
6
+ def load_all (file_type, puppi_module = nil, notification_method = nil)
7
+ if file_type == 'data' and puppi_module != nil
8
+ file_glob = '*_'+puppi_module
9
+ elsif file_type == 'notifications' and notification_method != nil
10
+ file_glob = notification_method + '_*'
11
+ else
12
+ file_glob = '*'
13
+ end
14
+
15
+ @all = Array.new
16
+ Dir.glob(Puppi::puppidir+'/'+file_type+'/'+file_glob+'.yml').each do |file|
17
+ @all << File.basename(file, '.yml')
18
+ end
19
+ @all
20
+ end
21
+
22
+ def load_helperfile helper, action
23
+ @helpers = load_all('helpers') unless not @helpers.nil?
24
+ raise 'Invalid Helper' unless @helpers.include? helper
25
+ @helper_content = YAML.load(File.read(Puppi::puppidir+"/helpers/"+helper+".yml"))
26
+ @helper_commands = Array.new
27
+ return nil unless not @helper_content[action.to_sym].nil?
28
+ @helper_content[action.to_sym].each do |command|
29
+ @helper_commands << Puppi::Files::Helper.new(command)
30
+ end
31
+ @helper_commands
32
+ end
33
+
34
+ def load_datafile file
35
+ @datafiles = load_all('data') unless not @datafiles.nil?
36
+ raise 'Invalid Datafile' unless @datafiles.include? file
37
+ Puppi::Files::Datafile.new(YAML.load(File.read(Puppi::puppidir+"/data/"+file+".yml")))
38
+ end
39
+
40
+ def load_notification file
41
+ @notifications = load_all('notifications') unless not @notifications.nil?
42
+ raise 'Invalid Notification' unless @notifications.include? file
43
+ Puppi::Files::Notification.new(YAML.load(File.read(Puppi::puppidir+"/notifications/"+file+".yml")))
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,40 @@
1
+ module Puppi
2
+ class Notification
3
+
4
+ attr_reader :notify_methods
5
+
6
+ def initialize(notifications, output)
7
+ @notify_methods = Array.new
8
+
9
+ if notifications.empty?
10
+ notifier = Puppi::Notifications::Stdout.new
11
+ notifier.output(output)
12
+ @notify_methods << 'stdout'
13
+ return
14
+ end
15
+ @loader = Puppi::Loader.new
16
+ validate_notifications_methods notifications
17
+ notifications.each do |notification|
18
+ notifier = Puppi::Notifications.class_eval(notification.capitalize).new
19
+ if notifier.respond_to? 'output'
20
+ notifier.output(output)
21
+ @notify_methods << notification
22
+ end
23
+ end
24
+ end
25
+
26
+ def validate_notifications_methods (notifications)
27
+ notifications.each do |notification|
28
+ if !valid_method? notification
29
+ raise "unknown notification method"
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+ def valid_method? (method)
36
+ @valid_methods = Puppi::Notifications.constants.select {|c| Class === Puppi::Notifications.const_get(c)}
37
+ @valid_methods.include? method.capitalize.to_sym
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ require 'mail'
2
+
3
+ module Puppi
4
+ module Notifications
5
+ class Mail
6
+ def initialize
7
+ @loader = Puppi::Loader.new
8
+ end
9
+
10
+ def output(output)
11
+ @@output = output
12
+ mails = load_all
13
+ mails.each do |mail|
14
+ mailer = @loader.load_notification(mail)
15
+ send_mail (mailer) if valid_mailer? (mailer)
16
+ end
17
+ end
18
+
19
+ private
20
+ def send_mail (mail)
21
+ mail = ::Mail.new do
22
+ from mail.variables[:from]
23
+ to mail.variables[:to]
24
+ subject mail.variables[:subject]
25
+ body @@output
26
+ end
27
+ mail.deliver!
28
+ end
29
+
30
+ def valid_mailer? (mailer)
31
+ return false if mailer.class != Puppi::Files::Notification
32
+ required_fields = %w[ from to subject ]
33
+ required_fields.each do |required_field|
34
+ return false unless mailer.variables.has_key? required_field.to_sym
35
+ end
36
+ return true
37
+ end
38
+
39
+ def load_all
40
+ @loader.load_all('notifications', nil, 'mail')
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,12 @@
1
+ module Puppi
2
+ module Notifications
3
+ class Stdout
4
+ def initialize
5
+ end
6
+
7
+ def output(output)
8
+ puts output
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Puppi
2
+ VERSION = "0.0.1alpha"
3
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "puppi/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "puppi"
7
+ s.version = Puppi::VERSION
8
+ s.authors = ["Celso Fernandes"]
9
+ s.email = ["fernandes@zertico.com"]
10
+ s.homepage = "http://fernandes.github.com/puppi"
11
+ s.summary = %q{Puppet module to manage applications deployments and servers local management}
12
+ s.description = <<-EOF
13
+ Puppi is a Puppet module that lets sysadmins standardize, manage and automate the deployment of web applications
14
+ and provides quick and standard commands to obtain informations about the system and what’s is going on it.
15
+
16
+ Its structure provides FULL flexibility on the actions required for virtually any kind of application deployment
17
+ and information gathering.
18
+ EOF
19
+
20
+ s.rubyforge_project = "puppi"
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+
27
+ # specify any dependencies here; for example:
28
+ # s.add_development_dependency "rspec"
29
+ # s.add_runtime_dependency "rest-client"
30
+ end
File without changes
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+ require 'puppi'
3
+
4
+ # ar = {:action => 'info', :puppi_module => 'hostname', :notification => ['mail', 'mq']}
5
+
6
+ describe "Puppi::Action" do
7
+
8
+ before(:each) do
9
+ Puppi::initial_checks
10
+ Puppi::GenerateSampleData.new.helpers
11
+ Puppi::GenerateSampleData.new.datafiles
12
+ end
13
+
14
+ it "should respond to check action" do
15
+ ar = {:action => 'check', :puppi_module => nil}
16
+ Puppi::Action.new({:action => 'check', :puppi_module => nil}).should respond_to(:execute).with(1).argument
17
+ end
18
+
19
+ it "should respond to log action" do
20
+ Puppi::Action.new({:action => 'log', :puppi_module => nil}).should respond_to(:execute).with(1).argument
21
+ end
22
+
23
+ it "should respond to info action" do
24
+ Puppi::Action.new({:action => 'info', :puppi_module => nil}).should respond_to(:execute).with(1).argument
25
+ end
26
+
27
+ it "should not respond to an unknown action" do
28
+ expect { Puppi::Action.new({:action => :unknow_action, :puppi_module => nil}) }.to raise_error "No Action Found"
29
+ end
30
+
31
+ it "should return module name if puppi module is specified" do
32
+ Puppi::Action.new({:action => 'check', :puppi_module => 'openssh'}).puppi_module.to_s.should match(/openssh/)
33
+ end
34
+
35
+ it "should return nil as module name name if no puppi module is specified" do
36
+ Puppi::Action.new({:action => 'check', :puppi_module => nil}).puppi_module.should be_a(NilClass)
37
+ end
38
+
39
+ it "should return all command output when running info command" do
40
+ output = Puppi::Action.new({:action => 'info', :puppi_module => nil}).output
41
+ output.should be_an(Array)
42
+ output.should have(2).items
43
+ output.should include("+ hostname +\n")
44
+ output.should include("+ openssh +\n")
45
+ end
46
+
47
+ it "should return all command output when running check command" do
48
+ output = Puppi::Action.new({:action => 'check', :puppi_module => nil}).output
49
+ output.should be_an(Array)
50
+ output.should have(4).items
51
+ output.should include("| hostname |\n")
52
+ output.should include(nil)
53
+ output.should include("| openssh |\n")
54
+ output.should include("| 1.0 |\n")
55
+ end
56
+ end
File without changes
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+ require 'puppi'
3
+ require 'fileutils'
4
+
5
+ describe "Puppi::Helper" do
6
+
7
+ before(:each) do
8
+ Puppi::initial_checks
9
+ Puppi::GenerateSampleData.new.helpers
10
+ #Puppi::GenerateSampleData.new.datafiles
11
+ end
12
+
13
+ it "should return a array with all helpers" do
14
+ #Dir.glob(Puppi::puppidir+'/helpers/*.yml')
15
+ end
16
+ end
File without changes
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+ require 'puppi'
3
+ require 'fileutils'
4
+
5
+ describe "Puppi::GenerateSampleData" do
6
+
7
+ before(:each) do
8
+ Puppi::initial_checks
9
+ Puppi::GenerateSampleData.new.helpers
10
+ Puppi::GenerateSampleData.new.datafiles
11
+ Puppi::GenerateSampleData.new.notifications
12
+ end
13
+
14
+ it "should the standard helper" do
15
+ standard_helper = File.open(Puppi::puppidir+'/helpers/standard.yml', 'rb') { |file| file.read }
16
+ standard_helper.should eql '---
17
+ :info:
18
+ -
19
+ :command: echo "+ %{name} +"
20
+ :description: "info module name for tests"
21
+ :check:
22
+ -
23
+ :command: echo "| %{name} |"
24
+ :description: "check module name for tests"
25
+ -
26
+ :command: echo "| %{version} |"
27
+ :description: "check module version"'
28
+ end
29
+
30
+ it "should the standard datafile for openssh module" do
31
+ standard_helper = File.open(Puppi::puppidir+'/data/standard_openssh.yml', 'rb') { |file| file.read }
32
+ standard_helper.should eql '---
33
+ name: openssh
34
+ version: 1.0'
35
+ end
36
+
37
+ it "should the standard datafile for hostname module" do
38
+ standard_helper = File.open(Puppi::puppidir+'/data/standard_hostname.yml', 'rb') { |file| file.read }
39
+ standard_helper.should eql '---
40
+ name: hostname'
41
+ end
42
+
43
+ it "should generate the standard notification to user1@mail.com for mail method" do
44
+ standard_helper = File.open(Puppi::puppidir+'/notifications/mail_user1.yml', 'rb') { |file| file.read }
45
+ standard_helper.should eql '---
46
+ from: puppi@puppi.com
47
+ to: user1@mail.com
48
+ subject: \'[puppi] notification\''
49
+ end
50
+
51
+ it "should generate the standard notification to user2@mail.com for mail method" do
52
+ standard_helper = File.open(Puppi::puppidir+'/notifications/mail_user2.yml', 'rb') { |file| file.read }
53
+ standard_helper.should eql '---
54
+ from: puppi@puppi.com
55
+ to: user2@mail.com
56
+ subject: \'[puppi] notification\''
57
+ end
58
+ end
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+ require 'puppi'
3
+
4
+ describe "Puppi::Loader" do
5
+
6
+ before(:each) do
7
+ @loader = Puppi::Loader.new
8
+ end
9
+
10
+ context "loading helpers" do
11
+ before(:each) do
12
+ Puppi::initial_checks
13
+ Puppi::GenerateSampleData.new.helpers
14
+ end
15
+
16
+ it "should load all helpers files" do
17
+ @helperfiles = @loader.load_all('helpers')
18
+ @helperfiles.should be_a(Array)
19
+ @helperfiles.should have(1).items
20
+ @helperfiles.should include('standard')
21
+ end
22
+ end
23
+
24
+ context "loading data files" do
25
+ before(:each) do
26
+ Puppi::initial_checks
27
+ Puppi::GenerateSampleData.new.datafiles
28
+ end
29
+
30
+ it "should load all data files" do
31
+ @datafiles = @loader.load_all('data')
32
+ @datafiles.should be_a(Array)
33
+ @datafiles.should have(2).items
34
+ end
35
+
36
+ it "should load all hostname data files" do
37
+ @datafiles = @loader.load_all('data', 'hostname')
38
+ @datafiles.should be_a(Array)
39
+ @datafiles.should have(1).items
40
+ end
41
+
42
+ it "should load all openssh standard data file" do
43
+ @p = @loader.load_datafile('standard_openssh')
44
+ @p.should be_a(Puppi::Files::Datafile)
45
+ @p.variables.should have(2).items
46
+ end
47
+
48
+ it "should load all hostname standard data file" do
49
+ @p = @loader.load_datafile('standard_hostname')
50
+ @p.should be_a(Puppi::Files::Datafile)
51
+ @p.variables.should have(1).items
52
+ end
53
+
54
+ it "should raise an exception for a invalid data file" do
55
+ expect { @loader.load_datafile('invalid_datafile') }.to raise_error("Invalid Datafile")
56
+ end
57
+ end
58
+
59
+ context "loading notification files" do
60
+ before(:each) do
61
+ Puppi::initial_checks
62
+ Puppi::GenerateSampleData.new.notifications
63
+ end
64
+
65
+ it "should load all notification files" do
66
+ @notifications = @loader.load_all('notifications')
67
+ @notifications.should be_a(Array)
68
+ @notifications.should have(2).items
69
+ end
70
+
71
+ it "should load all notification files for mail method" do
72
+ @notifications = @loader.load_all('notifications', 'mail')
73
+ @notifications.should be_a(Array)
74
+ @notifications.should have(2).items
75
+ end
76
+
77
+ it "should load all mail notification files" do
78
+ @p = @loader.load_notification('mail_user1')
79
+ @p.should be_a(Puppi::Files::Notification)
80
+ @p.variables.should have(3).items
81
+ end
82
+
83
+ it "should raise an exception for a invalid notification file" do
84
+ expect { @loader.load_notification('notification_invalid') }.to raise_error("Invalid Notification")
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+ require 'puppi'
3
+
4
+ describe "Puppi::Notification" do
5
+
6
+ before(:each) do
7
+ @loader = Puppi::Loader.new
8
+ end
9
+
10
+ it "should show raise exception when a unknown method is specified" do
11
+ expect { Puppi::Notification.new(['unknown'], 'output') }.to raise_error(RuntimeError)
12
+ end
13
+
14
+ it "should use stdout notification method when no one is specified" do
15
+ Puppi::Notification.new([], 'output').notify_methods.should include('stdout')
16
+ end
17
+
18
+ it "should use stdout notification method when specified" do
19
+ Puppi::Notification.new(['stdout'], 'output').notify_methods.should include('stdout')
20
+ end
21
+
22
+ it "should use mail notification method when specified" do
23
+ Puppi::Notification.new(['mail'], 'output').notify_methods.should include('mail')
24
+ end
25
+
26
+ it "should use mail and stdout notification methods when both are specified" do
27
+ @notifications_used = Puppi::Notification.new(['mail', 'stdout'], 'output')
28
+ @notifications_used.notify_methods.should include('mail')
29
+ @notifications_used.notify_methods.should include('stdout')
30
+ end
31
+ end
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+ require 'puppi'
3
+
4
+
5
+ describe "Puppi::Notifications::Mail" do
6
+ include Mail::Matchers
7
+
8
+ before(:all) do
9
+ Puppi::initial_checks
10
+ @generator = Puppi::GenerateSampleData.new
11
+ @generator.helpers
12
+ @generator.datafiles
13
+ @generator.notifications
14
+ Mail::TestMailer.deliveries.clear
15
+ mailer = Puppi::Notifications::Mail.new
16
+ mailer.output('puppi notification body')
17
+ end
18
+
19
+ it { should have_sent_email }
20
+ it { should have_sent_email.from('puppi@puppi.com') }
21
+ it { should have_sent_email.to('user1@mail.com').with_subject('[puppi] notification').with_body('puppi notification body') }
22
+ it { should have_sent_email.to('user2@mail.com').with_subject('[puppi] notification').with_body('puppi notification body') }
23
+
24
+ it "should return invalid mailer when its not a Puppi::Files::Notification class" do
25
+ Puppi::Notifications::Mail.publicize_methods do
26
+ Puppi::Notifications::Mail.new.valid_mailer?(false).should be_false
27
+ end
28
+ end
29
+
30
+ context "working with invalid mailer" do
31
+ before(:each) do
32
+ @hash = {"from"=>"puppi@puppi.com", "to"=>"user1@mail.com", "subject"=>"[puppi] notification"}
33
+ end
34
+ it "should return invalid when field 'to' is missing" do
35
+ Puppi::Notifications::Mail.publicize_methods do
36
+ @hash.delete('to')
37
+ notification = Puppi::Files::Notification.new(@hash)
38
+ Puppi::Notifications::Mail.new.valid_mailer?(notification).should be_false
39
+ end
40
+ end
41
+
42
+ it "should return invalid when field 'from' is missing" do
43
+ Puppi::Notifications::Mail.publicize_methods do
44
+ @hash.delete('from')
45
+ notification = Puppi::Files::Notification.new(@hash)
46
+ Puppi::Notifications::Mail.new.valid_mailer?(notification).should be_false
47
+ end
48
+ end
49
+
50
+ it "should return invalid when field 'subject' is missing" do
51
+ Puppi::Notifications::Mail.publicize_methods do
52
+ @hash.delete('subject')
53
+ notification = Puppi::Files::Notification.new(@hash)
54
+ Puppi::Notifications::Mail.new.valid_mailer?(notification).should be_false
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+ require 'puppi'
3
+
4
+ describe "Puppi" do
5
+ context "initial checks" do
6
+ it "should provide puppidir path" do
7
+ puppidir = Puppi::puppidir.should match(/(\/.+)+/)
8
+ end
9
+
10
+ it "should create puppi data directory if it does not exists" do
11
+ File.exists?(Puppi::puppidir+'/data').should be_false
12
+ Puppi::initial_checks
13
+ File.exists?(Puppi::puppidir+'/data').should be_true
14
+ end
15
+
16
+ it "should create puppi helpers directory if it does not exists" do
17
+ File.exists?(Puppi::puppidir+'/helpers').should be_false
18
+ Puppi::initial_checks
19
+ File.exists?(Puppi::puppidir+'/helpers').should be_true
20
+ end
21
+
22
+ it "should create puppi notifications directory if it does not exists" do
23
+ File.exists?(Puppi::puppidir+'/notifications').should be_false
24
+ Puppi::initial_checks
25
+ File.exists?(Puppi::puppidir+'/notifications').should be_true
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,60 @@
1
+ require 'fakefs/spec_helpers'
2
+ require 'mail'
3
+ require 'simplecov'
4
+
5
+ SimpleCov.start do
6
+ add_filter('/vendor\/ruby/')
7
+ end
8
+
9
+ # Load support files
10
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11
+
12
+ Mail.defaults do
13
+ delivery_method :test # in practice you'd do this in spec_helper.rb
14
+ end
15
+
16
+ RSpec.configure do |config|
17
+ # Ativa output colorido
18
+ config.color_enabled = true
19
+ # Define qual o framework de mocks.
20
+ # Pode ser :rspec, :mocha, :rr, :flexmock, :none
21
+ config.mock_framework = :rspec
22
+ # Ativa o modo de debug.
23
+ # É necessário ter o ruby-debug instalado.
24
+ #config.debug = true
25
+ # Exibe backtrace completo caso algum exemplo falhe.
26
+ config.full_backtrace = true
27
+ # Define uma expressão regular que irá evitar que uma
28
+ # linha do backtrace apareça quando um exemplo falha.
29
+ config.backtrace_clean_patterns << /vendor\//
30
+ # Inclui um módulo. Os métodos desse módulo estarão disponíveis no
31
+ # contexto dos métodos `it`, `specify`, `before`, `after` e `around`.
32
+ config.include Module.new
33
+ # Inclui um módulo somente nos grupos que casarem o padrão
34
+ # especificado pela opção `:file_path`. Esses arquivos irão
35
+ # ser definidos como sendo do tipo `:foo`, e irão carregar
36
+ # somente módulos deste tipo.
37
+ config.include Module.new, :type => :foo, :example_group => {:file_path => /spec\/robots/}
38
+ config.include FakeFS::SpecHelpers
39
+ # Estende o grupo de exemplos com o módulo especificado.
40
+ # Os métodos deste módulo estão disponíveis no contexto
41
+ # dos métodos `describe` e `context`.
42
+ config.extend Module.new
43
+ # Executa o bloco antes de cada exemplo de um grupo.
44
+ config.before {}
45
+ # Executa o bloco antes de todos os exemplos de um grupo.
46
+ config.before(:all) {}
47
+ # Executa o bloco depois de cada exemplo de um grupo.
48
+ #config.after {}
49
+ # Executa o bloco depois de todos os exemplos de um grupo.
50
+ config.after(:all) {}
51
+ # Executa o bloco antes e depois de cada exemplo de um grupo.
52
+ #config.around {}
53
+ # Para a execução da suíte no primeiro exemplo que falhar.
54
+ config.fail_fast = true
55
+ # Executa somente os exemplos que possuirem o filtro `:slow`.
56
+ # config.filter_run :slow => true
57
+ # Não executa os exemplos caso o bloco retorne um valor que seja
58
+ # avaliado como `true`.
59
+ #config.exclusion_filter = {:ruby => lambda {|version| RUBY_VERSION.to_s !~ /^#{version.to_s}/ }}
60
+ end
@@ -0,0 +1,8 @@
1
+ class Class
2
+ def publicize_methods
3
+ saved_private_instance_methods = self.private_instance_methods
4
+ self.class_eval { public *saved_private_instance_methods }
5
+ yield
6
+ self.class_eval { private *saved_private_instance_methods }
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1alpha
5
+ prerelease: 5
6
+ platform: ruby
7
+ authors:
8
+ - Celso Fernandes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-06 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! "Puppi is a Puppet module that lets sysadmins standardize, manage and
15
+ automate the deployment of web applications \nand provides quick and standard commands
16
+ to obtain informations about the system and what’s is going on it.\n\nIts structure
17
+ provides FULL flexibility on the actions required for virtually any kind of application
18
+ deployment \nand information gathering.\n"
19
+ email:
20
+ - fernandes@zertico.com
21
+ executables:
22
+ - puppi
23
+ extensions: []
24
+ extra_rdoc_files: []
25
+ files:
26
+ - .autotest
27
+ - .gitignore
28
+ - .rvmrc
29
+ - .travis.yml
30
+ - Gemfile
31
+ - README.rdoc
32
+ - Rakefile
33
+ - autotest/discover.rb
34
+ - bin/puppi
35
+ - etc/data/standard_openssh.yaml
36
+ - etc/helpers/standard.yaml
37
+ - etc/t.rb
38
+ - lib/puppi.rb
39
+ - lib/puppi/action.rb
40
+ - lib/puppi/files/datafile.rb
41
+ - lib/puppi/files/helper.rb
42
+ - lib/puppi/files/notification.rb
43
+ - lib/puppi/generate_sample_data.rb
44
+ - lib/puppi/loader.rb
45
+ - lib/puppi/notification.rb
46
+ - lib/puppi/notifications/mail.rb
47
+ - lib/puppi/notifications/stdout.rb
48
+ - lib/puppi/version.rb
49
+ - puppi.gemspec
50
+ - spec/core/rake_task.rb
51
+ - spec/puppi/action_spec.rb
52
+ - spec/puppi/files/datafile_spec.rb
53
+ - spec/puppi/files/helper_spec.rb
54
+ - spec/puppi/files/notification_spec.rb
55
+ - spec/puppi/generate_sample_data_spec.rb
56
+ - spec/puppi/loader_spec.rb
57
+ - spec/puppi/notification_spec.rb
58
+ - spec/puppi/notifications/mail_spec.rb
59
+ - spec/puppi_spec.rb
60
+ - spec/spec_helper.rb
61
+ - spec/support/publicize_methods.rb
62
+ homepage: http://fernandes.github.com/puppi
63
+ licenses: []
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ segments:
75
+ - 0
76
+ hash: -3422487645257531727
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>'
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.1
83
+ requirements: []
84
+ rubyforge_project: puppi
85
+ rubygems_version: 1.8.24
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Puppet module to manage applications deployments and servers local management
89
+ test_files:
90
+ - spec/core/rake_task.rb
91
+ - spec/puppi/action_spec.rb
92
+ - spec/puppi/files/datafile_spec.rb
93
+ - spec/puppi/files/helper_spec.rb
94
+ - spec/puppi/files/notification_spec.rb
95
+ - spec/puppi/generate_sample_data_spec.rb
96
+ - spec/puppi/loader_spec.rb
97
+ - spec/puppi/notification_spec.rb
98
+ - spec/puppi/notifications/mail_spec.rb
99
+ - spec/puppi_spec.rb
100
+ - spec/spec_helper.rb
101
+ - spec/support/publicize_methods.rb