simp-cli 1.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE +27 -0
- data/README.md +48 -0
- data/Rakefile +142 -0
- data/bin/simp +5 -0
- data/lib/simp/cli.rb +88 -0
- data/lib/simp/cli/commands/bootstrap.rb +275 -0
- data/lib/simp/cli/commands/check.rb +163 -0
- data/lib/simp/cli/commands/cleancerts.rb +114 -0
- data/lib/simp/cli/commands/config.rb +235 -0
- data/lib/simp/cli/commands/doc.rb +14 -0
- data/lib/simp/cli/commands/passgen.rb +128 -0
- data/lib/simp/cli/commands/puppeteval.rb +82 -0
- data/lib/simp/cli/commands/runpuppet.rb +95 -0
- data/lib/simp/cli/config/item.rb +456 -0
- data/lib/simp/cli/config/item/add_ldap_to_hiera.rb +43 -0
- data/lib/simp/cli/config/item/answers_yaml_file_writer.rb +58 -0
- data/lib/simp/cli/config/item/certificates.rb +39 -0
- data/lib/simp/cli/config/item/client_nets.rb +65 -0
- data/lib/simp/cli/config/item/common_runlevel_default.rb +32 -0
- data/lib/simp/cli/config/item/dns_search.rb +48 -0
- data/lib/simp/cli/config/item/dns_servers.rb +57 -0
- data/lib/simp/cli/config/item/failover_log_servers.rb +27 -0
- data/lib/simp/cli/config/item/gateway.rb +32 -0
- data/lib/simp/cli/config/item/grub_password.rb +51 -0
- data/lib/simp/cli/config/item/hostname.rb +24 -0
- data/lib/simp/cli/config/item/hostname_conf.rb +48 -0
- data/lib/simp/cli/config/item/ipaddress.rb +46 -0
- data/lib/simp/cli/config/item/is_master_yum_server.rb +23 -0
- data/lib/simp/cli/config/item/ldap_base_dn.rb +38 -0
- data/lib/simp/cli/config/item/ldap_bind_dn.rb +34 -0
- data/lib/simp/cli/config/item/ldap_bind_hash.rb +28 -0
- data/lib/simp/cli/config/item/ldap_bind_pw.rb +24 -0
- data/lib/simp/cli/config/item/ldap_master.rb +33 -0
- data/lib/simp/cli/config/item/ldap_root_dn.rb +42 -0
- data/lib/simp/cli/config/item/ldap_root_hash.rb +35 -0
- data/lib/simp/cli/config/item/ldap_sync_dn.rb +24 -0
- data/lib/simp/cli/config/item/ldap_sync_hash.rb +28 -0
- data/lib/simp/cli/config/item/ldap_sync_pw.rb +26 -0
- data/lib/simp/cli/config/item/ldap_uri.rb +43 -0
- data/lib/simp/cli/config/item/log_servers.rb +27 -0
- data/lib/simp/cli/config/item/netmask.rb +39 -0
- data/lib/simp/cli/config/item/network_conf.rb +63 -0
- data/lib/simp/cli/config/item/network_dhcp.rb +27 -0
- data/lib/simp/cli/config/item/network_interface.rb +41 -0
- data/lib/simp/cli/config/item/network_setup_nic.rb +28 -0
- data/lib/simp/cli/config/item/ntp_servers.rb +69 -0
- data/lib/simp/cli/config/item/puppet_autosign.rb +66 -0
- data/lib/simp/cli/config/item/puppet_ca.rb +31 -0
- data/lib/simp/cli/config/item/puppet_ca_port.rb +28 -0
- data/lib/simp/cli/config/item/puppet_conf.rb +98 -0
- data/lib/simp/cli/config/item/puppet_fileserver.rb +104 -0
- data/lib/simp/cli/config/item/puppet_hosts_entry.rb +44 -0
- data/lib/simp/cli/config/item/puppet_server.rb +30 -0
- data/lib/simp/cli/config/item/puppet_server_ip.rb +25 -0
- data/lib/simp/cli/config/item/puppetdb_port.rb +25 -0
- data/lib/simp/cli/config/item/puppetdb_server.rb +26 -0
- data/lib/simp/cli/config/item/remove_ldap_from_hiera.rb +47 -0
- data/lib/simp/cli/config/item/rename_fqdn_yaml.rb +40 -0
- data/lib/simp/cli/config/item/rsync_base.rb +37 -0
- data/lib/simp/cli/config/item/rsync_server.rb +44 -0
- data/lib/simp/cli/config/item/rsync_timeout.rb +26 -0
- data/lib/simp/cli/config/item/set_grub_password.rb +19 -0
- data/lib/simp/cli/config/item/simp_yum_servers.rb +30 -0
- data/lib/simp/cli/config/item/use_auditd.rb +19 -0
- data/lib/simp/cli/config/item/use_fips.rb +46 -0
- data/lib/simp/cli/config/item/use_iptables.rb +22 -0
- data/lib/simp/cli/config/item/use_ldap.rb +19 -0
- data/lib/simp/cli/config/item/use_selinux.rb +32 -0
- data/lib/simp/cli/config/item/yum_repositories.rb +75 -0
- data/lib/simp/cli/config/item_list_factory.rb +236 -0
- data/lib/simp/cli/config/questionnaire.rb +86 -0
- data/lib/simp/cli/config/utils.rb +128 -0
- data/lib/simp/cli/lib/utils.rb +114 -0
- data/lib/simp/simp.rb +77 -0
- data/spec/lib/simp/cli/commands/config_spec.rb +42 -0
- data/spec/lib/simp/cli/config/item/add_ldap_to_hiera_spec.rb +58 -0
- data/spec/lib/simp/cli/config/item/answers_yaml_file_writer_spec.rb +86 -0
- data/spec/lib/simp/cli/config/item/certificates_spec.rb +50 -0
- data/spec/lib/simp/cli/config/item/client_nets_spec.rb +66 -0
- data/spec/lib/simp/cli/config/item/common_runlevel_default_spec.rb +27 -0
- data/spec/lib/simp/cli/config/item/dns_search_spec.rb +74 -0
- data/spec/lib/simp/cli/config/item/dns_servers_spec.rb +76 -0
- data/spec/lib/simp/cli/config/item/failover_log_servers_spec.rb +49 -0
- data/spec/lib/simp/cli/config/item/files/FakeCA/cacertkey +1 -0
- data/spec/lib/simp/cli/config/item/files/FakeCA/gencerts_nopass.sh +10 -0
- data/spec/lib/simp/cli/config/item/files/autosign.conf.new +11 -0
- data/spec/lib/simp/cli/config/item/files/autosign.conf.used +15 -0
- data/spec/lib/simp/cli/config/item/files/fileserver.conf +41 -0
- data/spec/lib/simp/cli/config/item/files/hosts +2 -0
- data/spec/lib/simp/cli/config/item/files/hosts.old_puppet_entry +3 -0
- data/spec/lib/simp/cli/config/item/files/puppet.conf +25 -0
- data/spec/lib/simp/cli/config/item/files/puppet.your.domain.yaml +21 -0
- data/spec/lib/simp/cli/config/item/files/resolv.conf__multiple +10 -0
- data/spec/lib/simp/cli/config/item/files/resolv.conf__single +4 -0
- data/spec/lib/simp/cli/config/item/files/rsyncd.conf +225 -0
- data/spec/lib/simp/cli/config/item/gateway_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/grub_password_spec.rb +24 -0
- data/spec/lib/simp/cli/config/item/hostname_conf_spec.rb +27 -0
- data/spec/lib/simp/cli/config/item/hostname_spec.rb +22 -0
- data/spec/lib/simp/cli/config/item/ipaddress_spec.rb +40 -0
- data/spec/lib/simp/cli/config/item/is_master_yum_server_spec.rb +29 -0
- data/spec/lib/simp/cli/config/item/ldap_base_dn_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/ldap_bind_dn_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/ldap_bind_hash_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/ldap_bind_pw_spec.rb +21 -0
- data/spec/lib/simp/cli/config/item/ldap_master_spec.rb +37 -0
- data/spec/lib/simp/cli/config/item/ldap_root_dn_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/ldap_root_hash_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/ldap_sync_dn_spec.rb +22 -0
- data/spec/lib/simp/cli/config/item/ldap_sync_hash_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/ldap_sync_pw_spec.rb +21 -0
- data/spec/lib/simp/cli/config/item/ldap_uri_spec.rb +32 -0
- data/spec/lib/simp/cli/config/item/log_servers_spec.rb +49 -0
- data/spec/lib/simp/cli/config/item/netmask_spec.rb +28 -0
- data/spec/lib/simp/cli/config/item/network_conf_spec.rb +63 -0
- data/spec/lib/simp/cli/config/item/network_dhcp_spec.rb +11 -0
- data/spec/lib/simp/cli/config/item/network_interface_spec.rb +26 -0
- data/spec/lib/simp/cli/config/item/network_setup_nic_spec.rb +29 -0
- data/spec/lib/simp/cli/config/item/ntp_servers_spec.rb +43 -0
- data/spec/lib/simp/cli/config/item/puppet_autosign_spec.rb +55 -0
- data/spec/lib/simp/cli/config/item/puppet_ca_port_spec.rb +23 -0
- data/spec/lib/simp/cli/config/item/puppet_ca_spec.rb +22 -0
- data/spec/lib/simp/cli/config/item/puppet_conf_spec.rb +110 -0
- data/spec/lib/simp/cli/config/item/puppet_fileserver_spec.rb +53 -0
- data/spec/lib/simp/cli/config/item/puppet_hosts_entry_spec.rb +85 -0
- data/spec/lib/simp/cli/config/item/puppet_server_ip_spec.rb +24 -0
- data/spec/lib/simp/cli/config/item/puppet_server_spec.rb +22 -0
- data/spec/lib/simp/cli/config/item/puppetdb_port_spec.rb +25 -0
- data/spec/lib/simp/cli/config/item/puppetdb_server_spec.rb +25 -0
- data/spec/lib/simp/cli/config/item/remove_ldap_from_hiera_spec.rb +58 -0
- data/spec/lib/simp/cli/config/item/rename_fqdn_yaml_spec.rb +63 -0
- data/spec/lib/simp/cli/config/item/rsync_base_spec.rb +28 -0
- data/spec/lib/simp/cli/config/item/rsync_server_spec.rb +41 -0
- data/spec/lib/simp/cli/config/item/rsync_timeout_spec.rb +21 -0
- data/spec/lib/simp/cli/config/item/set_grub_password_spec.rb +29 -0
- data/spec/lib/simp/cli/config/item/simp_yum_servers_spec.rb +41 -0
- data/spec/lib/simp/cli/config/item/spec_helper.rb +22 -0
- data/spec/lib/simp/cli/config/item/use_auditd_spec.rb +29 -0
- data/spec/lib/simp/cli/config/item/use_fips_spec.rb +29 -0
- data/spec/lib/simp/cli/config/item/use_iptables_spec.rb +29 -0
- data/spec/lib/simp/cli/config/item/use_ldap_spec.rb +29 -0
- data/spec/lib/simp/cli/config/item/use_selinux_spec.rb +24 -0
- data/spec/lib/simp/cli/config/item/yum_repositories_spec.rb +94 -0
- data/spec/lib/simp/cli/config/item_spec.rb +106 -0
- data/spec/lib/simp/cli/config/spec_helper.rb +1 -0
- data/spec/lib/simp/cli/config/utils_spec.rb +131 -0
- data/spec/lib/simp/cli/spec_helper.rb +1 -0
- data/spec/spec_helper.rb +91 -0
- 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
|
data/lib/simp/simp.rb
ADDED
@@ -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
|