Module: Shells::PfSenseCommon

Included in:
SerialPfSenseShell, SshPfSenseShell
Defined in:
lib/shells/pf_sense_common.rb

Overview

Common functionality for interacting with a pfSense device.

Defined Under Namespace

Classes: AlreadyInPfShell, MenuNavigationFailure, NotInPfShell, PublicKeyInvalid, PublicKeyNotFound, RestartNow, UserNotFound

Constant Summary collapse

'Enter an option:'
BASE_SHELL =

The base shell used when possible.

'/bin/sh'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#pf_sense_hostObject

Gets the hostname of the pfSense device.



75
76
77
# File 'lib/shells/pf_sense_common.rb', line 75

def pf_sense_host
  @pf_sense_host
end

#pf_sense_userObject

Gets the user currently logged into the pfSense device.



70
71
72
# File 'lib/shells/pf_sense_common.rb', line 70

def pf_sense_user
  @pf_sense_user
end

#pf_sense_versionObject

Gets the version of the pfSense firmware.



65
66
67
# File 'lib/shells/pf_sense_common.rb', line 65

def pf_sense_version
  @pf_sense_version
end

Class Method Details

.included(base) ⇒ Object

:nodoc:



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/shells/pf_sense_common.rb', line 79

def self.included(base)  #:nodoc:

  base.class_eval do
    # Trap the RestartNow exception.
    # When encountered, change the :quit option to '/sbin/reboot'.
    # This requires rewriting the @options instance variable since the hash is frozen
    # after initial validation.
    on_exception do |shell, ex|
      if ex.is_a?(Shells::PfSenseCommon::RestartNow)
        shell.send(:change_quit, '/sbin/reboot')
        :break
      end
    end

    add_hook :on_before_run do |sh|
      sh.instance_eval do
        self.pf_sense_version = nil
        self.pf_sense_user = nil
        self.pf_sense_host = nil
      end
    end

  end

end

Instance Method Details

#line_endingObject



113
114
115
# File 'lib/shells/pf_sense_common.rb', line 113

def line_ending
  @line_ending ||= "\n"
end

#pf_shell(&block) ⇒ Object

Executes the code block in the pfSense PHP shell.



161
162
163
# File 'lib/shells/pf_sense_common.rb', line 161

def pf_shell(&block)
  ::Shells::PfShellWrapper.new(self, &block).output
end

#setup_promptObject

:nodoc:



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/shells/pf_sense_common.rb', line 117

def setup_prompt #:nodoc:

  # By default we have the main menu.
  # We want to drop to the main shell to execute the PHP shell.
  # So we'll navigate the menu to get the option for the shell.
  # For this first navigation we allow a delay only if we are not connected to a serial device.
  # Serial connections are always on, so they don't need to initialize first.
  menu_option = get_menu_option 'Shell', !(Shells::SerialShell > self.class)
  raise MenuNavigationFailure unless menu_option

  # For 2.3 and 2.4 this is a valid match.
  # If future versions change the default prompt, we need to change our process.
  # [VERSION][USER@HOSTNAME]/root:  where /root is the current dir.
  shell_regex = /\[(?<VER>[^\]]*)\]\[(?<USERHOST>[^\]]*)\](?<CD>\/.*):\s*$/

  # Now we execute the menu option and wait for the shell_regex to match.
  temporary_prompt(shell_regex) do
    exec menu_option.to_s, command_timeout: 5

    # Once we have a match we should be able to repeat it and store the information from the shell.
    data = prompt_match.match(output)
    self.pf_sense_version = data['VER']
    self.pf_sense_user, _, self.pf_sense_host = data['USERHOST'].partition('@')
  end

  # at this point we can now treat it like a regular tcsh shell.
  command = "set prompt='#{options[:prompt]}'"
  exec_ignore_code command, silence_timeout: 10, command_timeout: 10, timeout_error: true, get_output: false
end

#teardownObject

:nodoc:



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/shells/pf_sense_common.rb', line 147

def teardown #:nodoc:
  # use the default teardown to exit the shell.
  super

  # then navigate to the logout option (if the shell is still active).
  if active?
    menu_option = get_menu_option 'Logout'
    raise MenuNavigationFailure unless menu_option
    exec_ignore_code menu_option.to_s, command_timeout: 1, timeout_error: false
  end
end

#validate_optionsObject

:nodoc:



105
106
107
108
109
110
111
# File 'lib/shells/pf_sense_common.rb', line 105

def validate_options  #:nodoc:
  super
  options[:shell] = :shell
  options[:quit] = 'exit'
  options[:retrieve_exit_code] = false
  options[:on_non_zero_exit_code] = :ignore
end