Module: Ncio::Support

Included in:
App
Defined in:
lib/ncio/support.rb,
lib/ncio/support/transform.rb,
lib/ncio/support/retry_action.rb,
lib/ncio/support/option_parsing.rb

Overview

Support module to mix into other classes, particularly the application and API classes. This support module provides a centralized logging configuration, and common methods to access configuration options about the behavior of the program.

Defined Under Namespace

Modules: OptionParsing, RetryAction, Transform

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#optsObject (readonly)

Returns the value of attribute opts.



13
14
15
# File 'lib/ncio/support.rb', line 13

def opts
  @opts
end

Class Method Details

.logObject

Logging is handled centrally, the helper methods will delegate to the centrally configured logging instance.



45
46
47
# File 'lib/ncio/support.rb', line 45

def self.log
  @log || reset_logging!
end

.map_file_option(filepath) ⇒ String

Map a file option to STDOUT, STDERR or a fully qualified file path.

Parameters:

  • filepath (String)

    A relative or fully qualified file path, or the keyword strings 'STDOUT' or 'STDERR'

Returns:

  • (String)

    file path or $stdout or $sederr



56
57
58
59
60
61
62
63
64
# File 'lib/ncio/support.rb', line 56

def self.map_file_option(filepath)
  case filepath
  when 'STDOUT' then $stdout
  when 'STDERR' then $stderr
  when 'STDIN' then $stdin
  when 'STRING' then StringIO.new
  else File.expand_path(filepath)
  end
end

.reset_logging!(opts) ⇒ Logger

Reset the global logger instance and return it as an object.

Returns:

  • (Logger)

    initialized logging instance



19
20
21
22
# File 'lib/ncio/support.rb', line 19

def self.reset_logging!(opts)
  logger = opts[:syslog] ? syslog_logger : stream_logger(opts)
  @log = logger
end

.stream_logger(opts) ⇒ Object

Return a new Logger instance configured for file output



33
34
35
36
37
38
39
40
# File 'lib/ncio/support.rb', line 33

def self.stream_logger(opts)
  out = map_file_option(opts[:logto])
  logger = Logger.new(out)
  logger.level = Logger::WARN
  logger.level = Logger::INFO if opts[:verbose]
  logger.level = Logger::DEBUG if opts[:debug]
  logger
end

.syslog_loggerObject

Return a new Syslog::Logger instance configured for syslog output



26
27
28
29
# File 'lib/ncio/support.rb', line 26

def self.syslog_logger
  # Use the daemon facility, matching Puppet behavior.
  Syslog::Logger.new('ncio', Syslog::LOG_DAEMON)
end

Instance Method Details

#apiObject

Memoized helper method to instantiate an API instance assuming options are available.



86
87
88
# File 'lib/ncio/support.rb', line 86

def api
  @api ||= Ncio::Api::V1.new(opts)
end

#debug(msg) ⇒ Object

Logs a message at the debug (syslog debug) log level i.e. Information useful to developers for debugging the application.



122
123
124
# File 'lib/ncio/support.rb', line 122

def debug(msg)
  log.debug msg
end

#error(msg) ⇒ Object

Logs a message at the error (syslog warning) log level. i.e. May indicate that an error will occur if action is not taken. e.g. A non-root file system has only 2GB remaining.



100
101
102
# File 'lib/ncio/support.rb', line 100

def error(msg)
  log.error msg
end

#fatal(msg) ⇒ Object

Logs a message at the fatal (syslog err) log level



92
93
94
# File 'lib/ncio/support.rb', line 92

def fatal(msg)
  log.fatal msg
end

#fileObject



130
131
132
# File 'lib/ncio/support.rb', line 130

def file
  opts[:file]
end

#format_error(e) ⇒ Object

Format an exception for logging. JSON is used to aid centralized log systems such as Logstash and Splunk

Parameters:

  • e (Exception)

    the exception to format



163
164
165
166
# File 'lib/ncio/support.rb', line 163

def format_error(e)
  data = { error: e.class.to_s, message: e.message, backtrace: e.backtrace }
  JSON.pretty_generate(data)
end

#friendly_error(e) ⇒ Object

Top level exception handler and friendly error message handler.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/ncio/support.rb', line 170

def friendly_error(e)
  case e
  when Ncio::Support::RetryAction::RetryException::Timeout
    'Timeout expired connecting to the console service.  Verify it is up and running.'
  when OpenSSL::SSL::SSLError
    friendly_ssl_error(e)
  when Ncio::Api::V1::ApiAuthenticationError
    'Make sure the --cert option value is listed in the certificate whitelist, '\
    'and you are able to run puppet agent --test on the master. '\
    'The certificate whitelist on the master is located at '\
    '/etc/puppetlabs/console-services/rbac-certificate-whitelist'
  else
    e.message
  end
end

#friendly_ssl_error(e) ⇒ Object

Handle SSL errors as a special case



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/ncio/support.rb', line 188

def friendly_ssl_error(e)
  case e.message
  when %r{read server hello A}
    'The socket connected, but there is no SSL service on the other side. '\
    'This is often the case with TCP forwarding, e.g. in Vagrant '\
    'or with SSH tunnels.'
  when %r{state=error: certificate verify failed}
    'The socket connected, but the certificate presented by the service could not '\
    'be verified.  Make sure the value of the --cacert option points to an identical '\
    'copy of the /etc/puppetlabs/puppet/ssl/certs/ca.pem file from the master.'
  when %r{returned=5 errno=0 state=SSLv3 read finished A}
    "The socket connected, but got back SSL error: #{e.message} "\
    'This usually means the value of the --cert and --key options are certificates '\
    'which are not signed by the same CA the service trusts.  This can often happen '\
    'if the service has recently been re-installed.  Please obtain a valid cert and key '\
    'and try again.'
  else
    "SSL Error: The socket is listening but something went wrong: #{e.message}"
  end
end

#info(msg) ⇒ Object

Logs a message at the info (syslog info) log level i.e. Normal operational messages that require no action. e.g. An application has started, paused or ended successfully.



115
116
117
# File 'lib/ncio/support.rb', line 115

def info(msg)
  log.info msg
end

#input_stream(input) ⇒ Object

Helper method to read from STDIN, or a file and execute an arbitrary block of code. A block must be passed which will recieve an IO object in the event input is a readable file path.



150
151
152
153
154
155
156
# File 'lib/ncio/support.rb', line 150

def input_stream(input)
  if input.is_a?(IO)
    yield input
  else
    File.open(input, 'r') { |stream| yield stream }
  end
end

#logObject



70
71
72
# File 'lib/ncio/support.rb', line 70

def log
  Ncio::Support.log
end

#map_file_option(filepath) ⇒ Object



66
67
68
# File 'lib/ncio/support.rb', line 66

def map_file_option(filepath)
  Ncio::Support.map_file_option(filepath)
end

#reset_logging!(opts) ⇒ Object

Reset the logging system, requires command line options to have been parsed.

Parameters:

  • Options (Hash<Symbol, String>)

    hash, passed to the support module



79
80
81
# File 'lib/ncio/support.rb', line 79

def reset_logging!(opts)
  Ncio::Support.reset_logging!(opts)
end

#uriObject



126
127
128
# File 'lib/ncio/support.rb', line 126

def uri
  opts[:uri]
end

#versionString

Return the application version as a Semantic Version encoded string

Returns:

  • (String)

    the version



213
214
215
# File 'lib/ncio/support.rb', line 213

def version
  Ncio::VERSION
end

#warn(msg) ⇒ Object

Logs a message at the warn (syslog notice) log level. e.g. Events that are unusual, but not error conditions.



107
108
109
# File 'lib/ncio/support.rb', line 107

def warn(msg)
  log.warn msg
end

#write_output(str, output) ⇒ Object

Helper method to write output, used for stubbing out the tests.

Parameters:

  • output (String, IO)

    the output path or a IO stream



138
139
140
141
142
143
144
# File 'lib/ncio/support.rb', line 138

def write_output(str, output)
  if output.is_a?(IO)
    output.puts(str)
  else
    File.open(output, 'w+') { |f| f.puts(str) }
  end
end