admin-utils 1.2.0
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.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +40 -0
- data/Rakefile +12 -0
- data/admin-utils.gemspec +24 -0
- data/lib/admin-utils.rb +10 -0
- data/lib/admin-utils/au_config.rb +43 -0
- data/lib/admin-utils/au_defaults.rb +30 -0
- data/lib/admin-utils/au_ftp.rb +104 -0
- data/lib/admin-utils/au_logger.rb +90 -0
- data/lib/admin-utils/au_util.rb +54 -0
- data/lib/admin-utils/string.rb +25 -0
- data/lib/admin-utils/version.rb +7 -0
- data/spec/admin-utils/au_config_spec.rb +73 -0
- data/spec/admin-utils/au_defaults_spec.rb +40 -0
- data/spec/admin-utils/au_ftp_spec.rb +58 -0
- data/spec/admin-utils/au_util_spec.rb +20 -0
- data/spec/admin-utils/string_spec.rb +22 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 359f5d2fa758b9fa2b453f6dbc1753696448abfa
|
4
|
+
data.tar.gz: 785e9751425618469417d4b82f3f7df0c2fdb15f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0f3ab116acf980ef44ee00239dd3f1f986a73aabc16aa41faac44351dc531af9b24c2bd0db85df60566d69b9ffd81650e0844047ab6755146931f3f3f5303fe2
|
7
|
+
data.tar.gz: 83d9b09e41f4fab949780585a6c3d501af9710116a6893b1407386bf214e6e95be7844a007c893633fc53a00dd85c2473e828a97faa116125aea065bfb90b50b
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
admin-utils (1.2.0)
|
5
|
+
log4r
|
6
|
+
rake
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
devver-construct (1.1.0)
|
12
|
+
diff-lcs (1.3)
|
13
|
+
fake_ftp (0.3.0)
|
14
|
+
log4r (1.1.10)
|
15
|
+
rake (12.3.1)
|
16
|
+
rspec (3.7.0)
|
17
|
+
rspec-core (~> 3.7.0)
|
18
|
+
rspec-expectations (~> 3.7.0)
|
19
|
+
rspec-mocks (~> 3.7.0)
|
20
|
+
rspec-core (3.7.1)
|
21
|
+
rspec-support (~> 3.7.0)
|
22
|
+
rspec-expectations (3.7.0)
|
23
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
+
rspec-support (~> 3.7.0)
|
25
|
+
rspec-mocks (3.7.0)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.7.0)
|
28
|
+
rspec-support (3.7.1)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
admin-utils!
|
35
|
+
devver-construct
|
36
|
+
fake_ftp
|
37
|
+
rspec
|
38
|
+
|
39
|
+
BUNDLED WITH
|
40
|
+
1.16.1
|
data/Rakefile
ADDED
data/admin-utils.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'admin-utils/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'admin-utils'
|
7
|
+
s.version = Au::Admin::Utils::VERSION
|
8
|
+
s.authors = 'Stefan Wendler'
|
9
|
+
s.email = 'stefan@binarysun.de'
|
10
|
+
s.homepage = 'https://github.com/mrmarbury/admin_utils'
|
11
|
+
s.licenses = 'Apache-2.0'
|
12
|
+
s.summary = 'The Admin Utils'
|
13
|
+
s.description = 'Some basic utilities that I need often when writing Ruby Code'
|
14
|
+
s.files = Dir.glob('{lib,spec}/**/*') + %w[Rakefile Gemfile Gemfile.lock admin-utils.gemspec]
|
15
|
+
s.test_files = Dir.glob('spec/**/*')
|
16
|
+
s.executables = Dir.glob('*.rb')
|
17
|
+
s.require_paths = %w[lib]
|
18
|
+
s.required_ruby_version = '~> 2.4'
|
19
|
+
s.add_dependency('log4r')
|
20
|
+
s.add_dependency('rake')
|
21
|
+
s.add_development_dependency('rspec')
|
22
|
+
s.add_development_dependency('devver-construct')
|
23
|
+
s.add_development_dependency('fake_ftp')
|
24
|
+
end
|
data/lib/admin-utils.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'yaml' unless defined? YAML
|
2
|
+
require 'admin-utils/au_defaults' unless defined? AuDefaults
|
3
|
+
require 'admin-utils/au_util' unless defined? AuUtil
|
4
|
+
|
5
|
+
module AuConfig
|
6
|
+
|
7
|
+
# Method that loads a yml file and return an object of type +OpenStruct+
|
8
|
+
#
|
9
|
+
# Params:
|
10
|
+
# * +config_file+ Name of the config file to load
|
11
|
+
# * +override_path+ Path to the directory that contains the yml file. If left blank, the default is taken which is configured in
|
12
|
+
# +AuDefaults+'s +CONFIG_PATH+ array. Can be either an array of path names or a single path as a string
|
13
|
+
#
|
14
|
+
# If +override_path+ is an array (e.g. when using the default), the first occurrence of the config file ist loaded.
|
15
|
+
def load_config(config_file, override_path = nil)
|
16
|
+
raise ArgumentError 'Plain config file name needed as string!' unless config_file
|
17
|
+
@config_path = AuDefaults.config_path override_path
|
18
|
+
begin
|
19
|
+
@configuration = get_config_file_for_path(@config_path, config_file)
|
20
|
+
logger.debug 'Using Config File: ' + @configuration.path
|
21
|
+
@yml_data = YAML.load @configuration
|
22
|
+
AuUtil.hash_to_ostruct @yml_data.merge(_config_file: @configuration.path)
|
23
|
+
rescue => error
|
24
|
+
logger.error "Error opening file #{@configuration}. The Message was: #{error.message}\n#{error.backtrace.join("\n")}"
|
25
|
+
raise
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
########
|
30
|
+
private
|
31
|
+
########
|
32
|
+
|
33
|
+
def get_config_file_for_path(cfg_path, config_file)
|
34
|
+
if cfg_path.respond_to? "each"
|
35
|
+
cfg_path.each do |path|
|
36
|
+
return File.new(File.join(path, config_file)) if File.exists? path + "/" + config_file
|
37
|
+
end
|
38
|
+
raise IOError, "File #{config_file} not found in path: #{cfg_path}"
|
39
|
+
else
|
40
|
+
File.new(File.join(cfg_path, config_file))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AuDefaults
|
2
|
+
|
3
|
+
LOGGER_BASE = '/var/log'
|
4
|
+
|
5
|
+
DEFAULT_INIT_SCRIPT_PATH = '/etc/init.d'
|
6
|
+
|
7
|
+
# Retrieves the default config path that holds the yml files for the current application.
|
8
|
+
# The +path+ variable can be used to override the default config path. The method can then be called
|
9
|
+
# without argument to retrieve the currently set config path.
|
10
|
+
#
|
11
|
+
# NOTE: As a default this method returns an array.
|
12
|
+
#
|
13
|
+
def config_path(path = nil)
|
14
|
+
AuDefaults.config_path(path)
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
|
19
|
+
CONFIG_PATH = [ ENV['HOME'] + '/.config', '/etc', '/usr/local/etc', '../config' ]
|
20
|
+
|
21
|
+
def config_path(path = nil)
|
22
|
+
@path_for_the_config = path || (@path_for_the_config || CONFIG_PATH)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Call this to reset the config path to the default values of the +CONFIG_PATH+ array
|
26
|
+
def reset_config_path
|
27
|
+
@path_for_the_config = nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'net/ftp' unless defined? Net::FTP
|
2
|
+
require 'open3' unless defined? Open3
|
3
|
+
require 'admin-utils/au_logger' unless defined? AuLogger
|
4
|
+
|
5
|
+
include AuLogger
|
6
|
+
|
7
|
+
module AuFtp
|
8
|
+
|
9
|
+
# Transfers files to a remote ftp host
|
10
|
+
#
|
11
|
+
# Params:
|
12
|
+
# * +ftp+ Valid object of type +Net::FTP+. The connection must be open
|
13
|
+
# * +directory+ The remote directory the files are put to.
|
14
|
+
# * +transfered_file+ A single file or an array of files that should be transfered
|
15
|
+
#
|
16
|
+
# Raises:
|
17
|
+
# * +Net::FTPPermError+ if there is a FTP permission problem of any kind
|
18
|
+
# * +Net::FTPError+ if anything goes wrong during FTP transfer
|
19
|
+
# * +TypeError+ if any of the input variables have the wrong type (including being nil)
|
20
|
+
#
|
21
|
+
def transfer_via_ftp(ftp, directory, transfered_files)
|
22
|
+
raise "\"ftp\" must be an object of type Net::FTP and the conenction must be open" unless ftp.is_a? Net::FTP
|
23
|
+
begin
|
24
|
+
entry_dir = ftp.pwd
|
25
|
+
ftp.chdir directory
|
26
|
+
if transfered_files.empty?
|
27
|
+
logger.warn "No file(s) for ftp transfer to directory \"#{directory}\" given. Doing nothing ... "
|
28
|
+
elsif transfered_files.respond_to?("each")
|
29
|
+
transfered_files.each do |file|
|
30
|
+
logger.info "Putting file \"#{file}\" to ftp server"
|
31
|
+
ftp.putbinaryfile file
|
32
|
+
end
|
33
|
+
else
|
34
|
+
logger.info "Putting single file \"#{transfered_files}\" to ftp server"
|
35
|
+
ftp.putbinaryfile transfered_files
|
36
|
+
end
|
37
|
+
ftp.chdir entry_dir
|
38
|
+
rescue Net::FTPPermError => ftpPerm
|
39
|
+
logger.error "Permission problems encountered during ftp transfer. Message was: " +
|
40
|
+
ftpPerm.message + "\n" + ftpPerm.backtrace.join("\n")
|
41
|
+
close_ftp_connection ftp
|
42
|
+
raise
|
43
|
+
rescue TypeError => typeError
|
44
|
+
logger.error "A type error occured. Make sure all variables contain the correct value types and are not nil! Message was: " +
|
45
|
+
typeError.message + "\n" + typeError.backtrace.join("\n")
|
46
|
+
close_ftp_connection ftp
|
47
|
+
raise
|
48
|
+
rescue Net::FTPError => ftpError
|
49
|
+
logger.error "Error during ftp transfer. Message was:" +
|
50
|
+
ftpError.message + "\n" + ftpError.backtrace.join("\n")
|
51
|
+
close_ftp_connection ftp
|
52
|
+
raise
|
53
|
+
else
|
54
|
+
logger.info "ftp transfer finished successfully"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Opens an FTP connection
|
59
|
+
# Basically it is a convenience method that wraps the +Net::FTP+ methods
|
60
|
+
# +connect+ and +login+. So the input variables match those needed by those two
|
61
|
+
# methods.
|
62
|
+
#
|
63
|
+
# NOTE: +port+, +user+, +passwd+, +acct+ can be nil. +port+ will be set to 21 by default.
|
64
|
+
#
|
65
|
+
def open_ftp_connection(host, port=21, user=nil, passwd=nil, acct=nil)
|
66
|
+
begin
|
67
|
+
logger.info "Opening ftp connection"
|
68
|
+
|
69
|
+
ftp = Net::FTP.new
|
70
|
+
ftp.connect(host, port)
|
71
|
+
ftp.login(user,passwd,acct)
|
72
|
+
rescue Net::FTPPermError => ftp_perm
|
73
|
+
logger.error "Permission problems encountered during ftp connect. Message was: " +
|
74
|
+
ftp_perm.message + "\n" + ftp_perm.backtrace.join("\n")
|
75
|
+
close_ftp_connection ftp
|
76
|
+
raise
|
77
|
+
rescue Net::FTPError => ftp_error
|
78
|
+
logger.error "Error during ftp operation. Message was:" +
|
79
|
+
ftp_error.message + "\n" + ftp_error.backtrace.join("\n")
|
80
|
+
close_ftp_connection ftp
|
81
|
+
raise
|
82
|
+
rescue SocketError => socket_error
|
83
|
+
logger.error "There was an error while accessing a socket. The Message was: " +
|
84
|
+
socket_error.message + "\n" + socket_error.backtrace.join("\n")
|
85
|
+
raise
|
86
|
+
end
|
87
|
+
ftp
|
88
|
+
end
|
89
|
+
|
90
|
+
# Closes the ftp conncetion given as parameter +ftp+ which must be a valid object of type +Net::FTP+
|
91
|
+
#
|
92
|
+
# NOTE: Does nothing, when +ftp+ is nil. Just logs a warning message in case a +Net::FTPConnectionError+ is catched.
|
93
|
+
#
|
94
|
+
def close_ftp_connection(ftp)
|
95
|
+
raise "\"ftp\" must be an object of type Net::FTP" unless ftp.is_a? Net::FTP
|
96
|
+
begin
|
97
|
+
ftp.close unless ftp.nil?
|
98
|
+
rescue Net::FTPConnectionError => conError
|
99
|
+
logger.warn "There was an error when trying to close the ftp connection. The message was: #{conError.message}"
|
100
|
+
else
|
101
|
+
logger.info "Ftp connection closed"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'log4r' unless defined? Log4r
|
2
|
+
|
3
|
+
module AuLogger
|
4
|
+
|
5
|
+
# Retrieves the current logger instance or initializes a new one.
|
6
|
+
#
|
7
|
+
# For parameters to use during initialization, see +AuLogger.initialize_logger+
|
8
|
+
#
|
9
|
+
# Default Usage Example:
|
10
|
+
#
|
11
|
+
# logger.info "my info text"
|
12
|
+
#
|
13
|
+
#
|
14
|
+
def logger(hash={})
|
15
|
+
AuLogger.logger(hash)
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
|
20
|
+
PATTERN="%d -= %l =- : %m"
|
21
|
+
UNINITIALIZED_NAME='UNINITIALIZED'
|
22
|
+
|
23
|
+
def logger(hash={})
|
24
|
+
@logger ||= initialize_logger(hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Used to initialize the logging system.
|
28
|
+
#
|
29
|
+
# Params:
|
30
|
+
# * +hash+ The hash containing all config varables
|
31
|
+
#
|
32
|
+
# The possible +hash+ variables are as follows:
|
33
|
+
# * :mode => The logging mode to use. See below. If unset, command line only logging will be used
|
34
|
+
# * :filename => Path to the logfile that should be written
|
35
|
+
# * :name => The name the logger will have (See +Log4r+ documentation on this!). Default is 'UNINITIALIZED_NAME'
|
36
|
+
# * :level => The log level according to +Log4r::<LEVEL>+ (See +Log4r+ documentation on this!). Set to INFO by default
|
37
|
+
# * :additive => Is the logger additive (See +Log4r+ documentation on this!)
|
38
|
+
# * :trace => Record trace information (See +Log4r+ documentation on this!)
|
39
|
+
#
|
40
|
+
# Example:
|
41
|
+
#
|
42
|
+
# AuLogger.initialize_logger(
|
43
|
+
# name: 'my_logger',
|
44
|
+
# filename: '/var/log/my_logger.log'
|
45
|
+
# )
|
46
|
+
#
|
47
|
+
# Current Modes:
|
48
|
+
# * +cronjob+ Log everything to a log file but messages with level WARN and above to stdout as well so they will be included in the crond status email
|
49
|
+
# * +daemon+ Log to a log file only
|
50
|
+
# * +dual+ Log everything to log file and to the console
|
51
|
+
#
|
52
|
+
def initialize_logger(hash={})
|
53
|
+
Log4r.define_levels(*Log4r::Log4rConfig::LogLevels)
|
54
|
+
@mode = (hash[:mode] or '')
|
55
|
+
@filename = (hash[:filename] or nil)
|
56
|
+
@ncurses_window = (hash[:ncurses_window] or nil)
|
57
|
+
@logger = Log4r::Logger.new(
|
58
|
+
(hash[:name] or UNINITIALIZED_NAME),
|
59
|
+
(hash[:level] or Log4r::INFO),
|
60
|
+
(hash[:additive]),
|
61
|
+
(hash[:trace])
|
62
|
+
)
|
63
|
+
|
64
|
+
log_pattern = Log4r::PatternFormatter.new(pattern: (hash[:pattern] or PATTERN))
|
65
|
+
|
66
|
+
if @mode == 'cronjob'
|
67
|
+
raise ArgumentError, 'Path to a log file must be added in cronjob mode!' unless @filename
|
68
|
+
@logger.outputters = Log4r::StdoutOutputter.new('cronjob stdout', level: Log4r::WARN, formatter: log_pattern)
|
69
|
+
@logger.add Log4r::FileOutputter.new('log', filename: @filename, formatter: log_pattern)
|
70
|
+
@logger.debug 'Logger initialized in cronjob mode'
|
71
|
+
elsif @mode == 'daemon'
|
72
|
+
raise ArgumentError, 'Path to a log file needed in daemon mode!' unless @filename
|
73
|
+
@logger.outputters = Log4r::FileOutputter.new('daemon log', filename: @filename, formatter: log_pattern)
|
74
|
+
@logger.debug 'Logger initialized in daemon mode'
|
75
|
+
elsif @mode == 'dual'
|
76
|
+
raise ArgumentError, 'Path to a log file needed in dual mode!' unless @filename
|
77
|
+
@logger.outputters = Log4r::StdoutOutputter.new('dual stdout', formatter: log_pattern)
|
78
|
+
@logger.add Log4r::FileOutputter.new('log', filename: @filename, formatter: log_pattern)
|
79
|
+
@logger.debug 'Logger initialized in dual mode. Log output will be logged to Console and Logfile'
|
80
|
+
else
|
81
|
+
@logger.outputters = Log4r::StdoutOutputter.new('stdout', formatter: log_pattern)
|
82
|
+
@logger.debug 'Logger initialized for stdout only mode'
|
83
|
+
end
|
84
|
+
if logger.name == UNINITIALIZED_NAME
|
85
|
+
logger.debug 'Logger uses the default name at the moment'
|
86
|
+
end
|
87
|
+
@logger
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'ostruct' unless defined? OpenStruct
|
2
|
+
|
3
|
+
module AuUtil
|
4
|
+
|
5
|
+
def self.hash_to_ostruct(object)
|
6
|
+
return case object
|
7
|
+
when Hash
|
8
|
+
object = object.clone
|
9
|
+
object.each do |key, value|
|
10
|
+
object[key] = hash_to_ostruct(value)
|
11
|
+
end
|
12
|
+
OpenStruct.new(object)
|
13
|
+
when Array
|
14
|
+
object = object.clone
|
15
|
+
object.map! { |i| hash_to_ostruct(i) }
|
16
|
+
else
|
17
|
+
object
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Basicaly this method can unzip any gzipped file
|
22
|
+
#
|
23
|
+
# Params:
|
24
|
+
# * +archive_name+ Filename (including path) of the dump file to extract
|
25
|
+
# * +extract_dir+ The directory the dump should be extracted to. If left +nil+, the dir name of the +dump_archive_name+ is used. Otherwise it is just set
|
26
|
+
# to "."
|
27
|
+
#
|
28
|
+
# Raises:
|
29
|
+
# * +File::IOError+ In case there was an error during extraction
|
30
|
+
#
|
31
|
+
def self.extract_gzip(archive_name, extract_dir = (File.dirname(archive_name) or '.'))
|
32
|
+
raise ArgumentError, "File #{archive_name} does not exist!" unless File.exists? archive_name
|
33
|
+
logger.info "Extracting \"#{archive_name}\" to directory \"#{extract_dir}\""
|
34
|
+
Open3.popen3 "gunzip -c #{archive_name} > " + extract_dir + "/" + File.basename(archive_name).chomp('.gz') do |stdin, stdout, stderr, t|
|
35
|
+
unless t.value.to_s.include? "exit 0"
|
36
|
+
raise File::IOError, "gzipped file #{archive_name} could not be extracted!\nThe error message was: #{stderr.read}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Executes Unix which and checks, if a binary is in path. Only works on Unix alike systems
|
42
|
+
#
|
43
|
+
# Params:
|
44
|
+
# * +name+ Command to check for
|
45
|
+
#
|
46
|
+
# Returns:
|
47
|
+
# * +true+ - Command in path
|
48
|
+
# * +false+ - Command not in path
|
49
|
+
#
|
50
|
+
def self.command?(name)
|
51
|
+
`which #{name}`
|
52
|
+
$?.success?
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
# Custom String method to check if a string can be parsed to a number (Integer)
|
4
|
+
#
|
5
|
+
# This method is called directly on a String object
|
6
|
+
#
|
7
|
+
# Returns:
|
8
|
+
# * +true+ String can be parsed to an Integer
|
9
|
+
# * +false+ String can not be parsed to an Integer
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# require 'admin-utils/string'
|
14
|
+
# .
|
15
|
+
# .
|
16
|
+
# .
|
17
|
+
# puts "is a number" if "12345".is_number?
|
18
|
+
#
|
19
|
+
def is_number?
|
20
|
+
Integer(self)
|
21
|
+
true
|
22
|
+
rescue
|
23
|
+
false
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'construct'
|
3
|
+
require 'construct/helpers'
|
4
|
+
|
5
|
+
require 'admin-utils/au_logger'
|
6
|
+
require 'admin-utils/au_config'
|
7
|
+
require 'admin-utils/au_defaults'
|
8
|
+
require 'admin-utils/au_util'
|
9
|
+
|
10
|
+
include Construct::Helpers
|
11
|
+
include AuLogger
|
12
|
+
include AuConfig
|
13
|
+
|
14
|
+
describe "Loading Config Files" do
|
15
|
+
|
16
|
+
it "should load a config file from a single path" do
|
17
|
+
|
18
|
+
config_dir = "config/dir"
|
19
|
+
|
20
|
+
within_construct do |const|
|
21
|
+
const.directory config_dir do |dir|
|
22
|
+
dir.file('config.yml', 'rabbit_hole: kinky_fudge')
|
23
|
+
end
|
24
|
+
|
25
|
+
config = load_config('config.yml', config_dir)
|
26
|
+
config.rabbit_hole.should == 'kinky_fudge'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should load a config file when an array of paths is given" do
|
31
|
+
config_dir_one = 'config/dir/one'
|
32
|
+
config_dir_two = 'config/dir/two'
|
33
|
+
conf_dirs = [config_dir_two, config_dir_one]
|
34
|
+
|
35
|
+
within_construct do |const|
|
36
|
+
const.directory config_dir_one do |dir|
|
37
|
+
dir.file('config.yml', 'fiasco_drive: ladyada')
|
38
|
+
end
|
39
|
+
const.directory config_dir_two
|
40
|
+
|
41
|
+
config = load_config('config.yml', conf_dirs)
|
42
|
+
config.fiasco_drive.should == 'ladyada'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should load a the first found config file when an array of paths is given" do
|
47
|
+
config_dir_one = 'config/dir/one'
|
48
|
+
config_dir_two = 'config/dir/two'
|
49
|
+
conf_dirs = [config_dir_two, config_dir_one]
|
50
|
+
|
51
|
+
within_construct do |const|
|
52
|
+
const.directory config_dir_one do |dir|
|
53
|
+
dir.file('config.yml', 'fiasco_drive: ladyada')
|
54
|
+
end
|
55
|
+
const.directory config_dir_two do |dir|
|
56
|
+
dir.file('config.yml', 'fiasco_drive: bagel_and_a_smeer')
|
57
|
+
end
|
58
|
+
|
59
|
+
config = load_config('config.yml', conf_dirs)
|
60
|
+
config.fiasco_drive.should == 'bagel_and_a_smeer'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should raise an IOError, if it cannot find a config file' do
|
65
|
+
config_dir_one = 'config/dir/one'
|
66
|
+
config_dir_two = 'config/dir/two'
|
67
|
+
conf_dirs = [config_dir_two, config_dir_one]
|
68
|
+
|
69
|
+
within_construct do |const|
|
70
|
+
lambda { load_config('config.yml', conf_dirs) }.should raise_error(IOError)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'admin-utils/au_defaults'
|
3
|
+
|
4
|
+
describe "Defaults" do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
AuDefaults.reset_config_path
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have a couple of default variables with the apropriate values" do
|
11
|
+
AuDefaults::LOGGER_BASE.should == '/var/log'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return the default config path when called for the first time" do
|
15
|
+
AuDefaults.config_path.should == [ENV['HOME'] + '/.config', '/etc', '/usr/local/etc', '../config']
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return the the path, when given as argument" do
|
19
|
+
AuDefaults.config_path('test').should == 'test'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should always return the same path once initialized with it" do
|
23
|
+
AuDefaults.config_path('test').should == 'test'
|
24
|
+
AuDefaults.config_path.should == 'test'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return the new path, when reinitialized" do
|
28
|
+
AuDefaults.config_path('test').should == 'test'
|
29
|
+
AuDefaults.config_path('reinit').should == 'reinit'
|
30
|
+
AuDefaults.config_path.should == 'reinit'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return the default again, when reset" do
|
34
|
+
AuDefaults.config_path('test').should == 'test'
|
35
|
+
AuDefaults.config_path.should == 'test'
|
36
|
+
AuDefaults.reset_config_path
|
37
|
+
AuDefaults.config_path.should == [ENV['HOME'] + '/.config', '/etc', '/usr/local/etc', '../config']
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'admin-utils/au_ftp'
|
3
|
+
|
4
|
+
include AuFtp
|
5
|
+
|
6
|
+
describe "Ftp Works" do
|
7
|
+
|
8
|
+
it "should open an ftp connection" do
|
9
|
+
ftp = double('Ftp Server')
|
10
|
+
Net::FTP.should_receive(:new).and_return(ftp)
|
11
|
+
ftp.should_receive(:connect).with('host', 21)
|
12
|
+
ftp.should_receive(:login).with('user', 'passwd', 'acct')
|
13
|
+
AuFtp.open_ftp_connection('host', 21, 'user', 'passwd', 'acct')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should upload a file via ftp" do
|
17
|
+
ftp = Net::FTP.new
|
18
|
+
ftp.should_receive(:pwd)
|
19
|
+
ftp.should_receive(:chdir).with('test_dir')
|
20
|
+
ftp.should_receive(:putbinaryfile).with('test_file')
|
21
|
+
ftp.should_receive(:chdir)
|
22
|
+
transfer_via_ftp(ftp, 'test_dir', 'test_file')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should upload multiple files" do
|
26
|
+
ftp = Net::FTP.new
|
27
|
+
ftp.should_receive(:pwd)
|
28
|
+
ftp.should_receive(:chdir).with('test_dir')
|
29
|
+
ftp.should_receive(:putbinaryfile).with('file1')
|
30
|
+
ftp.should_receive(:putbinaryfile).with('file2')
|
31
|
+
ftp.should_receive(:chdir)
|
32
|
+
transfer_via_ftp(ftp, 'test_dir', %w[file1 file2])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not upload on an empty file string" do
|
36
|
+
ftp = Net::FTP.new
|
37
|
+
ftp.should_receive(:pwd)
|
38
|
+
ftp.should_receive(:chdir).with('test_dir')
|
39
|
+
ftp.should_not_receive(:putbinaryfile)
|
40
|
+
ftp.should_receive(:chdir)
|
41
|
+
transfer_via_ftp(ftp, 'test_dir', '')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not upload on an empty array" do
|
45
|
+
ftp = Net::FTP.new
|
46
|
+
ftp.should_receive(:pwd)
|
47
|
+
ftp.should_receive(:chdir).with('test_dir')
|
48
|
+
ftp.should_not_receive(:putbinaryfile).with([])
|
49
|
+
ftp.should_receive(:chdir)
|
50
|
+
transfer_via_ftp(ftp, 'test_dir', [])
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should close an ftp connection" do
|
54
|
+
ftp = Net::FTP.new
|
55
|
+
ftp.should_receive(:close)
|
56
|
+
close_ftp_connection(ftp)
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'admin-utils/au_util'
|
3
|
+
|
4
|
+
describe "Create OpenStruct from Hash" do
|
5
|
+
|
6
|
+
it "should convert a Hash to an OpenStruct" do
|
7
|
+
my_hash = { key1: "value", key2: "otherValue" }
|
8
|
+
my_ostruct = AuUtil.hash_to_ostruct my_hash
|
9
|
+
|
10
|
+
my_ostruct.key1.should == "value"
|
11
|
+
my_ostruct.key2.should == "otherValue"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should treat an array just like an array" do
|
15
|
+
my_array = %w[ word1 word2 ]
|
16
|
+
my_ostruct = AuUtil.hash_to_ostruct my_array
|
17
|
+
my_ostruct[0].should == "word1"
|
18
|
+
my_ostruct[1].should == "word2"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'admin-utils/string'
|
3
|
+
|
4
|
+
describe "Is Number Test" do
|
5
|
+
|
6
|
+
it "should tell the an integer disguised as a string can be parsed to an integer" do
|
7
|
+
"45".is_number?.should == true
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should tell that a string with letters and numbers is not an integer" do
|
11
|
+
"skd93l".is_number?.should == false
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should tell that a string with just letters is not an integer" do
|
15
|
+
"though shall not pass".is_number?.should == false
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should tell that a string containing a float is not an integer" do
|
19
|
+
"23.42".is_number?.should == false
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: admin-utils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stefan Wendler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: log4r
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: devver-construct
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fake_ftp
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Some basic utilities that I need often when writing Ruby Code
|
84
|
+
email: stefan@binarysun.de
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- Gemfile
|
90
|
+
- Gemfile.lock
|
91
|
+
- Rakefile
|
92
|
+
- admin-utils.gemspec
|
93
|
+
- lib/admin-utils.rb
|
94
|
+
- lib/admin-utils/au_config.rb
|
95
|
+
- lib/admin-utils/au_defaults.rb
|
96
|
+
- lib/admin-utils/au_ftp.rb
|
97
|
+
- lib/admin-utils/au_logger.rb
|
98
|
+
- lib/admin-utils/au_util.rb
|
99
|
+
- lib/admin-utils/string.rb
|
100
|
+
- lib/admin-utils/version.rb
|
101
|
+
- spec/admin-utils/au_config_spec.rb
|
102
|
+
- spec/admin-utils/au_defaults_spec.rb
|
103
|
+
- spec/admin-utils/au_ftp_spec.rb
|
104
|
+
- spec/admin-utils/au_util_spec.rb
|
105
|
+
- spec/admin-utils/string_spec.rb
|
106
|
+
homepage: https://github.com/mrmarbury/admin_utils
|
107
|
+
licenses:
|
108
|
+
- Apache-2.0
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '2.4'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.6.14
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: The Admin Utils
|
130
|
+
test_files:
|
131
|
+
- spec/admin-utils/string_spec.rb
|
132
|
+
- spec/admin-utils/au_util_spec.rb
|
133
|
+
- spec/admin-utils/au_config_spec.rb
|
134
|
+
- spec/admin-utils/au_ftp_spec.rb
|
135
|
+
- spec/admin-utils/au_defaults_spec.rb
|