Control-CLI-Extreme

 view release on metacpan or  search on metacpan

lib/Control/CLI/Extreme.pm  view on Meta::CPAN

package Control::CLI::Extreme;

use strict;
use warnings;
use Exporter qw( import );
use Carp;
use Control::CLI qw( :all );

my $Package = __PACKAGE__;
our $VERSION = '1.14';
our @ISA = qw(Control::CLI);
our %EXPORT_TAGS = (
		use	=> [qw(useTelnet useSsh useSerial useIPv6)],
		prompt	=> [qw(promptClear promptHide promptCredential)],
		args	=> [qw(parseMethodArgs suppressMethodArgs)],
		coderef	=> [qw(validCodeRef callCodeRef)],
		_rest	=> [qw(passphraseRequired parse_errmode stripLastLine poll)],
	);
push @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS;
Exporter::export_ok_tags('all');

########################################### Global Class Variables ###########################################

my $Space = " ";
my $CTRL_C = "\cC";
my $CTRL_U = "\cU";
my $CTRL_X = "\cX";
my $CTRL_Y = "\cY";
my $CTRL_Z = "\cZ";

my %LoginPatterns = ( # Patterns to check for during device login (Telnet/Serial) and initial connection to CLI
	bell		=>	"\x07",
	banner		=>	'Enter Ctrl-Y to begin',
	menu		=>	'Use arrow keys to highlight option, press <Return> or <Enter> to select option',
	submenu		=>	'Press Ctrl-R to return to previous menu.  Press Ctrl-C to return to Main Menu',
	username	=>	'Enter Username: ',
	password	=>	"Enter Password: \e[?", # Should match only on the initial password prompt and not subsequent ones where * are printed
	lastlogin	=>	'Failed retries since last login:',
	localfail	=>	'Incorrect',
	localfail_xos	=>	'Login incorrect',
	radiusfail	=>	'Access Denied from RADIUS',
	radiustimeout1	=>	'no response from RADIUS servers',
	radiustimeout2	=>	'No reply from RADIUS server',
	srbanner	=>	"\((?:Secure Router|VSP4K)",
	xlrbanner	=>	"\x0d************************************\n",
	ersbanner	=>	"\x0d* Ethernet Routing Switch",
	passportbanner	=>	"\x0d* Passport 8",
	pp1600banner	=>	"\x0d* Passport 16", # The 6 ensures this does not trigger on old Accelar 1x00
	vspbanner	=>	"All Rights Reserved.\n\x0dVirtual Services Platform",
	fabengbanner	=>	"Extreme Networks Fabric Engine",
	consoleLogMsg1	=>	"connected via console port", #On serial port: GlobalRouter SW INFO user rwa connected via console port
	consoleLogMsg2	=>	"Blocked unauthorized ACLI access",
	more1		=>	'----More (q=Quit, space/return=Continue)----',
	more2		=>	'--More--',
	wlan9100banner	=>	'Avaya Wi-Fi Access Point',
	xos		=>	'ExtremeXOS',
	switchEngine	=>	'Extreme Networks Switch Engine',
	isw		=>	'Product: ISW ',
	isw2		=>	'Product: ISW-4W-4WS-4X',
	iswMarvell	=>	'Product: ISW-24W-4X',
	slx		=>	'Welcome to the Extreme SLX-OS Software',
	eosChassis	=>	'   C H A S S I S',
	oneosbanner	=>	'System is ready for all commands',
);
my %Prm = ( # Hash containing list of named parameters returned by attributes
	bstk	=>	'BaystackERS',
	pers	=>	'PassportERS',
	xlr	=>	'Accelar',
	sr	=>	'SecureRouter',
	trpz	=>	'WLAN2300',
	xirrus	=>	'WLAN9100',
	xos	=>	'ExtremeXOS',
	isw	=>	'ISW',
	iswMarv	=>	'ISWmarvell',
	s200	=>	'Series200',
	wing	=>	'Wing',
	slx	=>	'SLX',
	hive	=>	'HiveOS',
	ipanema	=>	'Ipanema',
	eos	=>	'EnterasysOS',
	oneos	=>	'OneOS',
	generic	=>	'generic',
);

my %Attribute = (
	Global		=> [
			'family_type',
			'is_nncli',
			'is_acli',
			'model',
			'sw_version',
			'fw_version',
			'slots',
			'ports',
			'sysname',
			'base_mac',
			'serial_number',
			'baudrate',
			'max_baud',
			],

	$Prm{pers}	=> [
			'is_voss',
			'is_fabric_engine',
			'is_apls',
			'apls_box_type',
			'brand_name',
			'is_master_cpu',
			'is_dual_cpu',
			'cpu_slot',
			'is_ha',
			'stp_mode',

lib/Control/CLI/Extreme.pm  view on Meta::CPAN

					send	=> "\n",
				},
	$Prm{xos}		=> {
					pattern	=> '^   U->page up  D->page down ESC->exit',
					send	=> "\e",
				},
);

our %ErrorPatterns = ( # Patterns which indicated the last command sent generated a syntax error on the host device (if regex does not match full error message, it must end with .+)
	$Prm{bstk}		=>	'^('
					. '\s+\^\n.+'
					. '|% Invalid '						# "% Invalid input detected at '^' marker." OR "% Invalid QoS UBP [classifier] entry name" 
					. '|% Cannot modify settings'
					. '|% Bad (?:port|unit|format)'				# ife 33/1; ife 1/333; ife 1/1-2/2
					. '|% MLT \d+ does not exist or it is not enabled'
					. '|% No such VLAN'
					. '|% Bad VLAN list format\.'
					. '|% View name does not exist'				# snmp-server user admin read-view root write-view root notify-view root
					. '|% Partial configuration of \'.+?\' already exists\.'# same as above
					. '|% View already exists, you must first delete it\.'	# snmp-server view root 1
					. '|% User \w+ does not exist'				# no snmp-server user admindes
					. '|% User \'.+?\' already exists'			# snmp-server user admin md5 passwdvbn read-view root write-view root notify-view root
					. '|% Password length must be in range:' 		# username add rwa role-name RW password // rwa // rwa (with password security)
					. '|% Bad format, use forms:.+'				# vlan members add 71 1/6-1/7 (1/6-7 is correct)
				. ')',
	$Prm{pers}		=>	'^('
					. '\x07?\s+\^\n.+'
					. '|% Invalid input detected at \'\^\' marker\.'
					. '|.+? not found in path .+'
					. '|(?:parameter|object) .+? is out of range'
					. '| ?\x07?Error ?: .+'
					. '|Unable to .+'
					. '|% Not allowed on secondary cpu\.'
					. '|% Incomplete command\.'
					. '|% Vrf "[^"]+" does not exist'
					. '| ERROR: copy failed \(code:0x[\da-fA-F]+\)'
					. '|Save config to file [^ ]+ failed\.'
					. '|% Vlan \d+ does not exist'
					. '|Command not allowed MSTP RSTP mode\.'			# On MSTP switch : vlan create 101 type port 1
					. '|% Permission denied\.'					# TACACS commands not allowed
					. '|% Only (?:gigabit|fast) ethernet ports allowed'		# config interface gig on fastEth port or vice-versa
					. '|There are \d+ releases already on system. Please remove 1 to proceed'
					. '|can\'t \w+ ".+?" 0x\d+'					# delete /flash/.ssh -y : can't remove "/flash/.ssh" 0x300042
					. '|".+?" is ambiguous in path /.+'				# AccDist3:5#% do
					. '|Password change aborted\.'					# Creating snmpv3 usm user with enh-secure-mode and password does not meet complexity requirements
					. '|Invalid password. Authentication failed'			# username teamnoc level ro // invalid-old-pwd // ...
					. '|Passwords do not match. Password change aborted'		# username teamnoc level ro // valid-old-pwd // newpwd // diffpwd
					. '|Error: Prefix List ".+?" not found'				# no ip prefix-list "<non-existent>"
					. '|Invalid ipv4 address\.'					# filter acl ace action 11 6 permit redirect-next-hop 2000:100::201 (on a non-ipv6 acl)
					. '|\x07?error in getting .+'					# mlt 1 member 1/1 (where mlt does not exist)
					. '|\x07?Error In \w+ ?:'					# ip name-server primary <ip> (where <ip> is already set)
					. '|Invalid ip address format\.'				# ip bgp neighbor ''
				. ')',
	$Prm{xlr}		=>	'^('
					. '.+? not found'
					. '|(?:parameter|object) .+? is out of range'
				. ')',
	$Prm{sr}		=>	'^('
					. '\s+\^\n.+'
					. '|Error : Command .+? does not exist'
					. '|Config is locked by some other user'
				. ')',
	$Prm{trpz}		=>	'^('
					. '\s+\^\n.+'
					. '|Unrecognized command:.+'
					. '|Unrecognized command in this mode:.+'
				. ')',
	$Prm{xirrus}		=>	'^('
					. '\s+\^\n.+'
				. ')',
	$Prm{xos}		=>	'^('
					. '\x07?\s+\^\n.+'
					. '|Error: .*(?:already|not).+'
				. ')',
	$Prm{isw}		=>	'^('
					. '\s+\^\n.+'
					. '|% Incomplete command.'
					. '|% Invalid .+'						# ISW3(config)#% interface vlan 101; ISW3(config-if-vlan)#% ip igmp snooping : % Invalid IGMP VLAN 101!
					. '|% No such .+'						# ISW5(config)#% interface 10GigabitEthernet 1/6 : % No such interface: 10GigabitEthernet 1/6
				. ')',
	$Prm{iswMarv}		=>	'^('
					. 'Syntax Error\.'
				. ')',
	$Prm{s200}		=>	'^('
					. '\s+\^\n.+'
					. '|Command not found / Incomplete command.'
					. '|Failed to create.+'						# (Extreme 220) (Vlan)#vlan 6666
				. ')',
	$Prm{wing}		=>	'^('
					. '\s+\^\n.+'
					. '|%% Error:.+'
				. ')',
	$Prm{slx}		=>	'^('
					. '-+\^\n.+'
					. '|(?:%% )?Error ?: .+'
					. '|Error\(s\):\n.+'
				. ')',
	$Prm{hive}		=>	'^('
					. '\s+\^--'
				. ')',
	$Prm{ipanema}		=>	'('
					. '^\? Unknown command'
					. '|: No such file or directory'
					. '|: incorrect password'
				. ')',
	$Prm{eos}		=>	'^('
					. 'Error: '
				. ')',
	$Prm{oneos}		=>	'^('
					. '-+\^\n.+'
					. '|%?Error: '
				. ')',
);
our $CmdConfirmPrompt = '(?:' # Y/N prompt
				. '[\(\[<] *(?:'
						. '[yY](?:es)? *(?:[\\\/]|or) *[nN]o?'
						. '|[nN]o? *(?:[\\\/]|or) *[yY](?:es)?'
						. '|y - .+?, n - .+?, <cr> - .+?'
					. ') *[\)\]>](?: *(?:\[[yYnN]\])? *(?:[?:]|\? ?:) *| )'
				. '|Y - Yes, N - No: ' # ISWmarvell
			. ')$';



( run in 3.798 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )