simp-cli 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +27 -0
  3. data/README.md +48 -0
  4. data/Rakefile +142 -0
  5. data/bin/simp +5 -0
  6. data/lib/simp/cli.rb +88 -0
  7. data/lib/simp/cli/commands/bootstrap.rb +275 -0
  8. data/lib/simp/cli/commands/check.rb +163 -0
  9. data/lib/simp/cli/commands/cleancerts.rb +114 -0
  10. data/lib/simp/cli/commands/config.rb +235 -0
  11. data/lib/simp/cli/commands/doc.rb +14 -0
  12. data/lib/simp/cli/commands/passgen.rb +128 -0
  13. data/lib/simp/cli/commands/puppeteval.rb +82 -0
  14. data/lib/simp/cli/commands/runpuppet.rb +95 -0
  15. data/lib/simp/cli/config/item.rb +456 -0
  16. data/lib/simp/cli/config/item/add_ldap_to_hiera.rb +43 -0
  17. data/lib/simp/cli/config/item/answers_yaml_file_writer.rb +58 -0
  18. data/lib/simp/cli/config/item/certificates.rb +39 -0
  19. data/lib/simp/cli/config/item/client_nets.rb +65 -0
  20. data/lib/simp/cli/config/item/common_runlevel_default.rb +32 -0
  21. data/lib/simp/cli/config/item/dns_search.rb +48 -0
  22. data/lib/simp/cli/config/item/dns_servers.rb +57 -0
  23. data/lib/simp/cli/config/item/failover_log_servers.rb +27 -0
  24. data/lib/simp/cli/config/item/gateway.rb +32 -0
  25. data/lib/simp/cli/config/item/grub_password.rb +51 -0
  26. data/lib/simp/cli/config/item/hostname.rb +24 -0
  27. data/lib/simp/cli/config/item/hostname_conf.rb +48 -0
  28. data/lib/simp/cli/config/item/ipaddress.rb +46 -0
  29. data/lib/simp/cli/config/item/is_master_yum_server.rb +23 -0
  30. data/lib/simp/cli/config/item/ldap_base_dn.rb +38 -0
  31. data/lib/simp/cli/config/item/ldap_bind_dn.rb +34 -0
  32. data/lib/simp/cli/config/item/ldap_bind_hash.rb +28 -0
  33. data/lib/simp/cli/config/item/ldap_bind_pw.rb +24 -0
  34. data/lib/simp/cli/config/item/ldap_master.rb +33 -0
  35. data/lib/simp/cli/config/item/ldap_root_dn.rb +42 -0
  36. data/lib/simp/cli/config/item/ldap_root_hash.rb +35 -0
  37. data/lib/simp/cli/config/item/ldap_sync_dn.rb +24 -0
  38. data/lib/simp/cli/config/item/ldap_sync_hash.rb +28 -0
  39. data/lib/simp/cli/config/item/ldap_sync_pw.rb +26 -0
  40. data/lib/simp/cli/config/item/ldap_uri.rb +43 -0
  41. data/lib/simp/cli/config/item/log_servers.rb +27 -0
  42. data/lib/simp/cli/config/item/netmask.rb +39 -0
  43. data/lib/simp/cli/config/item/network_conf.rb +63 -0
  44. data/lib/simp/cli/config/item/network_dhcp.rb +27 -0
  45. data/lib/simp/cli/config/item/network_interface.rb +41 -0
  46. data/lib/simp/cli/config/item/network_setup_nic.rb +28 -0
  47. data/lib/simp/cli/config/item/ntp_servers.rb +69 -0
  48. data/lib/simp/cli/config/item/puppet_autosign.rb +66 -0
  49. data/lib/simp/cli/config/item/puppet_ca.rb +31 -0
  50. data/lib/simp/cli/config/item/puppet_ca_port.rb +28 -0
  51. data/lib/simp/cli/config/item/puppet_conf.rb +98 -0
  52. data/lib/simp/cli/config/item/puppet_fileserver.rb +104 -0
  53. data/lib/simp/cli/config/item/puppet_hosts_entry.rb +44 -0
  54. data/lib/simp/cli/config/item/puppet_server.rb +30 -0
  55. data/lib/simp/cli/config/item/puppet_server_ip.rb +25 -0
  56. data/lib/simp/cli/config/item/puppetdb_port.rb +25 -0
  57. data/lib/simp/cli/config/item/puppetdb_server.rb +26 -0
  58. data/lib/simp/cli/config/item/remove_ldap_from_hiera.rb +47 -0
  59. data/lib/simp/cli/config/item/rename_fqdn_yaml.rb +40 -0
  60. data/lib/simp/cli/config/item/rsync_base.rb +37 -0
  61. data/lib/simp/cli/config/item/rsync_server.rb +44 -0
  62. data/lib/simp/cli/config/item/rsync_timeout.rb +26 -0
  63. data/lib/simp/cli/config/item/set_grub_password.rb +19 -0
  64. data/lib/simp/cli/config/item/simp_yum_servers.rb +30 -0
  65. data/lib/simp/cli/config/item/use_auditd.rb +19 -0
  66. data/lib/simp/cli/config/item/use_fips.rb +46 -0
  67. data/lib/simp/cli/config/item/use_iptables.rb +22 -0
  68. data/lib/simp/cli/config/item/use_ldap.rb +19 -0
  69. data/lib/simp/cli/config/item/use_selinux.rb +32 -0
  70. data/lib/simp/cli/config/item/yum_repositories.rb +75 -0
  71. data/lib/simp/cli/config/item_list_factory.rb +236 -0
  72. data/lib/simp/cli/config/questionnaire.rb +86 -0
  73. data/lib/simp/cli/config/utils.rb +128 -0
  74. data/lib/simp/cli/lib/utils.rb +114 -0
  75. data/lib/simp/simp.rb +77 -0
  76. data/spec/lib/simp/cli/commands/config_spec.rb +42 -0
  77. data/spec/lib/simp/cli/config/item/add_ldap_to_hiera_spec.rb +58 -0
  78. data/spec/lib/simp/cli/config/item/answers_yaml_file_writer_spec.rb +86 -0
  79. data/spec/lib/simp/cli/config/item/certificates_spec.rb +50 -0
  80. data/spec/lib/simp/cli/config/item/client_nets_spec.rb +66 -0
  81. data/spec/lib/simp/cli/config/item/common_runlevel_default_spec.rb +27 -0
  82. data/spec/lib/simp/cli/config/item/dns_search_spec.rb +74 -0
  83. data/spec/lib/simp/cli/config/item/dns_servers_spec.rb +76 -0
  84. data/spec/lib/simp/cli/config/item/failover_log_servers_spec.rb +49 -0
  85. data/spec/lib/simp/cli/config/item/files/FakeCA/cacertkey +1 -0
  86. data/spec/lib/simp/cli/config/item/files/FakeCA/gencerts_nopass.sh +10 -0
  87. data/spec/lib/simp/cli/config/item/files/autosign.conf.new +11 -0
  88. data/spec/lib/simp/cli/config/item/files/autosign.conf.used +15 -0
  89. data/spec/lib/simp/cli/config/item/files/fileserver.conf +41 -0
  90. data/spec/lib/simp/cli/config/item/files/hosts +2 -0
  91. data/spec/lib/simp/cli/config/item/files/hosts.old_puppet_entry +3 -0
  92. data/spec/lib/simp/cli/config/item/files/puppet.conf +25 -0
  93. data/spec/lib/simp/cli/config/item/files/puppet.your.domain.yaml +21 -0
  94. data/spec/lib/simp/cli/config/item/files/resolv.conf__multiple +10 -0
  95. data/spec/lib/simp/cli/config/item/files/resolv.conf__single +4 -0
  96. data/spec/lib/simp/cli/config/item/files/rsyncd.conf +225 -0
  97. data/spec/lib/simp/cli/config/item/gateway_spec.rb +23 -0
  98. data/spec/lib/simp/cli/config/item/grub_password_spec.rb +24 -0
  99. data/spec/lib/simp/cli/config/item/hostname_conf_spec.rb +27 -0
  100. data/spec/lib/simp/cli/config/item/hostname_spec.rb +22 -0
  101. data/spec/lib/simp/cli/config/item/ipaddress_spec.rb +40 -0
  102. data/spec/lib/simp/cli/config/item/is_master_yum_server_spec.rb +29 -0
  103. data/spec/lib/simp/cli/config/item/ldap_base_dn_spec.rb +23 -0
  104. data/spec/lib/simp/cli/config/item/ldap_bind_dn_spec.rb +23 -0
  105. data/spec/lib/simp/cli/config/item/ldap_bind_hash_spec.rb +23 -0
  106. data/spec/lib/simp/cli/config/item/ldap_bind_pw_spec.rb +21 -0
  107. data/spec/lib/simp/cli/config/item/ldap_master_spec.rb +37 -0
  108. data/spec/lib/simp/cli/config/item/ldap_root_dn_spec.rb +23 -0
  109. data/spec/lib/simp/cli/config/item/ldap_root_hash_spec.rb +23 -0
  110. data/spec/lib/simp/cli/config/item/ldap_sync_dn_spec.rb +22 -0
  111. data/spec/lib/simp/cli/config/item/ldap_sync_hash_spec.rb +23 -0
  112. data/spec/lib/simp/cli/config/item/ldap_sync_pw_spec.rb +21 -0
  113. data/spec/lib/simp/cli/config/item/ldap_uri_spec.rb +32 -0
  114. data/spec/lib/simp/cli/config/item/log_servers_spec.rb +49 -0
  115. data/spec/lib/simp/cli/config/item/netmask_spec.rb +28 -0
  116. data/spec/lib/simp/cli/config/item/network_conf_spec.rb +63 -0
  117. data/spec/lib/simp/cli/config/item/network_dhcp_spec.rb +11 -0
  118. data/spec/lib/simp/cli/config/item/network_interface_spec.rb +26 -0
  119. data/spec/lib/simp/cli/config/item/network_setup_nic_spec.rb +29 -0
  120. data/spec/lib/simp/cli/config/item/ntp_servers_spec.rb +43 -0
  121. data/spec/lib/simp/cli/config/item/puppet_autosign_spec.rb +55 -0
  122. data/spec/lib/simp/cli/config/item/puppet_ca_port_spec.rb +23 -0
  123. data/spec/lib/simp/cli/config/item/puppet_ca_spec.rb +22 -0
  124. data/spec/lib/simp/cli/config/item/puppet_conf_spec.rb +110 -0
  125. data/spec/lib/simp/cli/config/item/puppet_fileserver_spec.rb +53 -0
  126. data/spec/lib/simp/cli/config/item/puppet_hosts_entry_spec.rb +85 -0
  127. data/spec/lib/simp/cli/config/item/puppet_server_ip_spec.rb +24 -0
  128. data/spec/lib/simp/cli/config/item/puppet_server_spec.rb +22 -0
  129. data/spec/lib/simp/cli/config/item/puppetdb_port_spec.rb +25 -0
  130. data/spec/lib/simp/cli/config/item/puppetdb_server_spec.rb +25 -0
  131. data/spec/lib/simp/cli/config/item/remove_ldap_from_hiera_spec.rb +58 -0
  132. data/spec/lib/simp/cli/config/item/rename_fqdn_yaml_spec.rb +63 -0
  133. data/spec/lib/simp/cli/config/item/rsync_base_spec.rb +28 -0
  134. data/spec/lib/simp/cli/config/item/rsync_server_spec.rb +41 -0
  135. data/spec/lib/simp/cli/config/item/rsync_timeout_spec.rb +21 -0
  136. data/spec/lib/simp/cli/config/item/set_grub_password_spec.rb +29 -0
  137. data/spec/lib/simp/cli/config/item/simp_yum_servers_spec.rb +41 -0
  138. data/spec/lib/simp/cli/config/item/spec_helper.rb +22 -0
  139. data/spec/lib/simp/cli/config/item/use_auditd_spec.rb +29 -0
  140. data/spec/lib/simp/cli/config/item/use_fips_spec.rb +29 -0
  141. data/spec/lib/simp/cli/config/item/use_iptables_spec.rb +29 -0
  142. data/spec/lib/simp/cli/config/item/use_ldap_spec.rb +29 -0
  143. data/spec/lib/simp/cli/config/item/use_selinux_spec.rb +24 -0
  144. data/spec/lib/simp/cli/config/item/yum_repositories_spec.rb +94 -0
  145. data/spec/lib/simp/cli/config/item_spec.rb +106 -0
  146. data/spec/lib/simp/cli/config/spec_helper.rb +1 -0
  147. data/spec/lib/simp/cli/config/utils_spec.rb +131 -0
  148. data/spec/lib/simp/cli/spec_helper.rb +1 -0
  149. data/spec/spec_helper.rb +91 -0
  150. metadata +391 -0
@@ -0,0 +1,86 @@
1
+ module Simp; end
2
+ class Simp::Cli; end
3
+ module Simp::Cli::Config; end
4
+
5
+ require File.expand_path( '../commands/config', File.dirname(__FILE__) )
6
+ require File.expand_path( 'utils', File.dirname(__FILE__) )
7
+
8
+ # Builds a SIMP configuration profile based on an Array of Config::Items
9
+ #
10
+ # The configuration profile is built on a Questionnaire, which is interactive
11
+ # by default, but can be automated.
12
+ #
13
+ class Simp::Cli::Config::Questionnaire
14
+
15
+ INTERACTIVE = 0
16
+ NONINTERACTIVE = 1
17
+ REALLY_NONINTERACTIVE = 2
18
+
19
+ def initialize( options = {} )
20
+ @options = {
21
+ :noninteractive => INTERACTIVE,
22
+ :verbose => 0
23
+ }.merge( options )
24
+ end
25
+
26
+
27
+ # processes an Array of Config::Items and returns a hash of Config::Item
28
+ # answers
29
+ def process( item_queue=[], answers={} )
30
+ if item = item_queue.shift
31
+ item.config_items = answers
32
+ process_item item
33
+
34
+ # add (or replace) this item's answer to the answers list
35
+ answers[ item.key ] = item
36
+
37
+ # add any next_items to the queue
38
+ item_queue = item.next_items + item_queue
39
+
40
+ process item_queue, answers
41
+ end
42
+
43
+ answers
44
+ end
45
+
46
+
47
+ # process a Config::Item
48
+ #
49
+ # simp config can run in the following modes:
50
+ # - interactive (prompt each item)
51
+ # - mostly non-interactive (-f/-A; prompt items that can't be inferred)
52
+ # - never prompt (-a/-ff);
53
+ # - never prompt (-ff; relies on cli args for non-inferrable items))
54
+ def process_item item
55
+ item.skip_query = true if @options[ :noninteractive ] >= NONINTERACTIVE
56
+ if @options.fetch( :fail_on_missing_answers, false )
57
+ item.fail_on_missing_answer = true
58
+ end
59
+
60
+ if @options[ :noninteractive ] == INTERACTIVE
61
+ item.query
62
+ else
63
+ value = item.default_value
64
+
65
+ if item.validate( value )
66
+ item.value = value
67
+ item.print_summary if @options.fetch( :verbose ) >= 0
68
+ else
69
+ # alert user that the value is wrong
70
+ print_invalid_item_error item
71
+
72
+ # present an interactive prompt for invalid answers unless '-ff'
73
+ exit 1 if @options.fetch( :noninteractive ) >= REALLY_NONINTERACTIVE
74
+ item.skip_query = false
75
+ value = item.query
76
+ end
77
+ end
78
+ item.safe_apply
79
+ end
80
+
81
+ def print_invalid_item_error item
82
+ error = "ERROR: '#{item.value}' is not a valid value for #{item.key}"
83
+ error += "\n#{item.not_valid_message}" if item.not_valid_message
84
+ say "<%= color(%q{#{error}}, RED) %>\n"
85
+ end
86
+ end
@@ -0,0 +1,128 @@
1
+ module Simp; end
2
+ class Simp::Cli; end
3
+ module Simp::Cli::Config
4
+ class PasswordError < StandardError; end
5
+ end
6
+
7
+ class Simp::Cli::Config::Utils
8
+ DEFAULT_PASSWORD_LENGTH = 32
9
+ class << self
10
+ def validate_fqdn fqdn
11
+ # snarfed from:
12
+ # https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch08s15.html
13
+ regex = %r{\A((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\Z}
14
+ ((fqdn =~ regex) ? true : false )
15
+ end
16
+
17
+
18
+ def validate_ip ip
19
+ # using the native 'resolv' class in order to minimize non-EL rubygems
20
+ # snarfed from:
21
+ # http://stackoverflow.com/questions/3634998/how-do-i-check-whether-a-value-in-a-string-is-an-ip-address
22
+ require 'resolv'
23
+ ((ip =~ Resolv::IPv4::Regex) || (ip =~ Resolv::IPv6::Regex)) ? true : false
24
+ end
25
+
26
+
27
+ def validate_hostname hostname
28
+ # based on:
29
+ # http://stackoverflow.com/questions/2532053/validate-a-hostname-string
30
+ #
31
+ # nicer solution that only works on ruby1.9+:
32
+ # ( hostname =~ %r{\A(?!-)[a-z0-9-]{1,63}(?<!-)\Z} ) ? true : false
33
+ #
34
+ # ruby1.8-safe version:
35
+ (( hostname =~ %r{\A[a-z0-9-]{1,63}\Z} ) ? true : false ) &&
36
+ (( hostname !~ %r{^-|-$} ) ? true : false )
37
+ end
38
+
39
+
40
+ def validate_netmask( x )
41
+ # a brute-force regexp that validates all possible valid netmasks
42
+ nums = '(128|192|224|240|248|252|254)'
43
+ znums = '(0|128|192|224|240|248|252|254)'
44
+ regex = /^((#{nums}\.0\.0\.0)|(255\.#{znums}\.0\.0)|(255\.255\.#{znums}\.0)|(255\.255\.255\.#{znums}))$/i
45
+ x =~ regex ? true: false
46
+ end
47
+
48
+
49
+ def validate_hiera_lookup( x )
50
+ x.to_s.strip =~ %r@\%\{.+\}@ ? true : false
51
+ end
52
+
53
+
54
+ # NOTE: requires shell-based cracklib
55
+ # TODO: should we find a better way of returning specific error messages than an exception?
56
+ def validate_password( password )
57
+ require 'shellwords'
58
+ if password.length < 8
59
+ raise Simp::Cli::Config::PasswordError, "Password must be at least 8 characters long"
60
+ false
61
+ else
62
+ pass_result = `echo #{Shellwords.escape(password)} | cracklib-check`.split(':').last.strip
63
+ if pass_result == "OK"
64
+ true
65
+ else
66
+ raise Simp::Cli::Config::PasswordError, "Invalid Password: #{pass_result}"
67
+ false
68
+ end
69
+ end
70
+ end
71
+
72
+
73
+ def generate_password( length = DEFAULT_PASSWORD_LENGTH )
74
+ password = ''
75
+ special_chars = ['#','%','&','*','+','-','.',':','@']
76
+ symbols = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a
77
+ Integer(length).times { |i| password += (symbols + special_chars)[rand((symbols.length-1 + special_chars.length-1))] }
78
+ # Ensure that the password does not start or end with a special
79
+ # character.
80
+ special_chars.include?(password[0].chr) and password[0] = symbols[rand(symbols.length-1)]
81
+ special_chars.include?(password[password.length-1].chr) and password[password.length-1] = symbols[rand(symbols.length-1)]
82
+ password
83
+ end
84
+
85
+
86
+ # pure-ruby openldap hash generator
87
+ def encrypt_openldap_hash( string, salt=nil )
88
+ require 'digest/sha1'
89
+ require 'base64'
90
+
91
+ # Ruby 1.8.7 hack to do Random.new.bytes(4):
92
+ salt = salt || (x = ''; 4.times{ x += ((rand * 255).floor.chr ) }; x)
93
+ digest = Digest::SHA1.digest( string + salt )
94
+
95
+ # NOTE: Digest::SHA1.digest in Ruby 1.9+ returns a String encoding in
96
+ # ASCII-8BIT, whereas all other Strings in play are UTF-8
97
+ if RUBY_VERSION.split('.')[0..1].join('.').to_f > 1.8
98
+ digest = digest.force_encoding( 'UTF-8' )
99
+ salt = salt.force_encoding( 'UTF-8' )
100
+ end
101
+
102
+ "{SSHA}"+Base64.encode64( digest + salt ).chomp
103
+ end
104
+
105
+
106
+ def validate_openldap_hash( x )
107
+ (x =~ %r@\{SSHA\}[A-Za-z0-9=+/]+@ ) ? true : false
108
+ end
109
+
110
+
111
+ def generate_certificates(
112
+ hostnames,
113
+ ca_dir='/etc/puppet/environments/simp/FakeCA'
114
+ )
115
+ result = true
116
+ Dir.chdir( ca_dir ) do
117
+ File.open('togen', 'w'){|file| hostnames.each{ |host| file.puts host }}
118
+
119
+ # NOTE: script must exist in ca_dir
120
+ result = system('./gencerts_nopass.sh auto') && result
121
+
122
+ # blank file so subsequent runs don't re-key our hosts
123
+ File.open('togen', 'w'){ |file| file.truncate(0) }
124
+ end
125
+ result
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,114 @@
1
+ module Utils
2
+ module_function
3
+
4
+ DEFAULT_PASSWORD_LENGTH = 32
5
+
6
+ def yes_or_no(prompt, default_yes)
7
+ print prompt + (default_yes ? ' [Y|n]: ' : ' [y|N]: ')
8
+ case STDIN.gets
9
+ when /^(y|Y)/
10
+ true
11
+ when /^(n|N)/
12
+ false
13
+ when /^\s*$/
14
+ default_yes
15
+ else
16
+ yes_or_no(prompt, default_yes)
17
+ end
18
+ end
19
+
20
+ def get_password
21
+ print 'Enter password: '
22
+
23
+ system('/bin/stty', '-echo')
24
+ password1 = STDIN.gets.strip
25
+ system('/bin/stty', 'echo')
26
+ puts
27
+
28
+ print 'Re-enter password: '
29
+ system('/bin/stty', '-echo')
30
+ password2 = STDIN.gets.strip
31
+ system('/bin/stty', 'echo')
32
+ puts
33
+
34
+ if password1 == password2
35
+ if validate_password(password1)
36
+ password1
37
+ else
38
+ get_password
39
+ end
40
+ else
41
+ puts " Passwords do not match! Please try again."
42
+ get_password
43
+ end
44
+ end
45
+
46
+ def generate_password(length = DEFAULT_PASSWORD_LENGTH, default_is_autogenerate = true)
47
+ password = ''
48
+ if Utils.yes_or_no('Do you want to autogenerate the password?', default_is_autogenerate )
49
+ special_chars = ['#','%','&','*','+','-','.',':','@']
50
+ symbols = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a
51
+ Integer(length).times { |i| password += (symbols + special_chars)[rand((symbols.length-1 + special_chars.length-1))] }
52
+ # Ensure that the password does not start or end with a special
53
+ # character.
54
+ special_chars.include?(password[0].chr) and password[0] = symbols[rand(symbols.length-1)]
55
+ special_chars.include?(password[password.length-1].chr) and password[password.length-1] = symbols[rand(symbols.length-1)]
56
+ puts "Your password is:\n#{password}"
57
+ print 'Push [ENTER] to continue.'
58
+ $stdout.flush
59
+ $stdin.gets
60
+ else
61
+ password = Utils.get_password
62
+ end
63
+ password
64
+ end
65
+
66
+ def validate_password(password)
67
+ require 'shellwords'
68
+
69
+ if password.length < 8
70
+ puts " Invalid Password: Password must be at least 8 characters long"
71
+ false
72
+ else
73
+ pass_result = `echo #{Shellwords.escape(password)} | cracklib-check`.split(':').last.strip
74
+ if pass_result == "OK"
75
+ true
76
+ else
77
+ puts " Invalid Password: #{pass_result}"
78
+ false
79
+ end
80
+ end
81
+ end
82
+
83
+ def get_value(default_value = '')
84
+ case default_value
85
+ when /\d+\.\d+\.\d+\.\d+/
86
+ print "Enter a new IP: "
87
+ value = STDIN.gets.strip
88
+ while !valid_ip?(value)
89
+ puts "INVALID! Try again..."
90
+ print "Enter a new IP: "
91
+ value = STDIN.gets.strip
92
+ end
93
+ else
94
+ print "Enter a value: "
95
+ value = STDIN.gets.strip
96
+ end
97
+ value
98
+ end
99
+
100
+ def generate_certificates(hostname)
101
+ Dir.chdir('/etc/puppet/Config/FakeCA') do
102
+ file = File.open('togen', 'w')
103
+ file.puts hostname
104
+ file.close
105
+
106
+ passphrase = `cat cacertkey`.chomp
107
+ system('./gencerts_nopass.sh auto')
108
+ end
109
+ end
110
+
111
+ def valid_ip?(value)
112
+ value.to_s =~ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
113
+ end
114
+ end
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+ class Simp
3
+ current_dir = File.dirname(File.expand_path(__FILE__)) + '/simp'
4
+
5
+ require 'optparse'
6
+ require current_dir + '/lib/utils'
7
+
8
+ protected
9
+ def self.menu
10
+ puts "Usage: simp [command]"
11
+ puts
12
+ puts " Commands"
13
+ @commands.each do |command_name, command_class|
14
+ puts " - " + command_name
15
+ end
16
+ puts " - help [command]"
17
+ puts
18
+ end
19
+
20
+ def self.help
21
+ puts @opt_parser.to_s
22
+ puts
23
+ end
24
+
25
+ def self.run(args = [])
26
+ @opt_parser.parse!
27
+ end
28
+
29
+ private
30
+ def self.version
31
+ begin
32
+ %x{rpm -q simp}.split(/\n/).last.match(/([0-9]+\.[0-9]+\.?[0-9]*)/)[1]
33
+ rescue
34
+ #raise "Simp is not installed!"
35
+ '4.1'
36
+ end
37
+ end
38
+
39
+ # load the commands from commands/*.rb and grab the classes that are simp commands
40
+ Dir.glob(current_dir + '/commands/*.rb').sort_by(&:to_s).each do |command_file|
41
+ require command_file
42
+ end
43
+
44
+ @commands = Simp::Commands::constants.inject({}) do |commands, constant|
45
+ obj = Simp::Commands.const_get(constant)
46
+ if obj.respond_to?(:superclass) and obj.superclass == Simp
47
+ commands[constant.to_s.downcase] = obj
48
+ end
49
+ commands
50
+ end
51
+ @commands['version'] = self
52
+
53
+ if ARGV.length == 0 or (ARGV.length == 1 and ARGV[0] == 'help')
54
+ menu
55
+ elsif ARGV[0] == 'version'
56
+ puts version
57
+ elsif ARGV[0] == 'help'
58
+ if (command = @commands[ARGV[1]]).nil?
59
+ puts "\n\033[31m#{ARGV[1]} is not a recognized command\033[39m\n\n"
60
+ menu
61
+ elsif ARGV[1] == 'version'
62
+ puts "Display the current version of SIMP."
63
+ else
64
+ command.help
65
+ end
66
+ elsif (command = @commands[ARGV[0]]).nil?
67
+ puts "\n\033[31m#{ARGV[0]} is not a recognized command\033[39m\n\n"
68
+ menu
69
+ else
70
+ begin
71
+ command.run(ARGV.drop(1))
72
+ rescue => e
73
+ puts "\n\033[31m#{e.message}\033[39m\n\n"
74
+ e.backtrace.first(10).each{|l| puts l }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,42 @@
1
+ require 'simp/cli/commands/config'
2
+ require 'simp/cli/config/item'
3
+ require_relative( '../spec_helper' )
4
+
5
+ require 'yaml'
6
+
7
+ describe Simp::Cli::Commands::Config do
8
+ ### describe ".print_answers_yaml" do
9
+ ### before :each do
10
+ ### ci = Simp::Cli::Config::Item.new
11
+ ### ci.key = 'item'
12
+ ### ci.value = 'foo'
13
+ ### ci.description = 'A simple item'
14
+ ### list = { foo: ci }
15
+ ###
16
+ ### ci = Simp::Cli::Config::ListItem.new
17
+ ### ci.key = 'list'
18
+ ### ci.value = ['one','two','three']
19
+ ### ci.description = 'A simple list'
20
+ ### list[ci.key] = ci
21
+ ###
22
+ ### ci = Simp::Cli::Config::YesNoItem.new
23
+ ### ci.key = 'yesno'
24
+ ### ci.value = true
25
+ ### ci.description = 'A simple yes/no item'
26
+ ### list[ci.key] = ci
27
+ ###
28
+ ### @simple_item_list = list
29
+ ### end
30
+ ###
31
+ ### it "prints yaml" do
32
+ ### io = StringIO.new
33
+ ### Simp::Cli::Commands::Config.print_answers_yaml io, @simple_item_list
34
+ ### y = YAML.load io.string
35
+ ### expect( y ).to be_kind_of Hash
36
+ ### expect( y ).not_to be_empty
37
+ ### expect( y['item'] ).to eq('foo')
38
+ ### expect( y['list'] ).to eq(['one','two','three'])
39
+ ### expect( y['yesno'] ).to eq(true)
40
+ ### end
41
+ ### end
42
+ end