package Net::FullAuto; ### OPEN SOURCE LICENSE - GNU AFFERO PUBLIC LICENSE Version 3.0 ####### # # Net::FullAuto - Distributed Workload Automation Software # Copyright © 2000-2024 Brian M. Kelly # # This program is free software: you can redistribute it and/or # modify it under the terms of the GNU Affero General Public License # as published by the Free Software Foundation, either version 3 of # the License, or any later version. # # This program is distributed in the hope that it will be useful, # but **WITHOUT ANY WARRANTY**; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public # License along with this program. If not, see: # . # ####################################################################### our $VERSION='1.0000751'; use 5.005; use strict; use warnings; BEGIN { my @ARGS=@ARGV; my $quiet=0; my $args=''; foreach (@ARGS) { if ($_ eq '--password') { $args.='--password '; shift @ARGS; $args.='******** ' if ($ARGS[0] && ((length $ARGS[0]<3) || (unpack('a2',$ARGS[0]) ne '--'))); next; } elsif ($_ eq '--quiet' || $_ eq '--version' || $_ =~ /^-[a-uw-zA-UW-Z]*[Vv]/ || $_ =~ '--cat') { $quiet=1; } $args.="$_ "; } chop $args; my $nl=(grep { $_ eq '--cron' } @ARGV)?'':"\n"; print "Command Line -> $0 $args\n" if !$nl; my $c=($^O ne 'MSWin32' && $^O ne 'MSWin64' && $^O ne 'cygwin' && !exists $ENV{PAR_TEMP})?'©':'(C)'; print "STARTING FullAuto$c on ". localtime() . "\n" if !$quiet && (-1) { chomp $line; $cpu=$line if -1 FullAuto.ps =head1 Name C - Fully Automate ANY Workload with *Persistent* SSH/SFTP from One Host =head1 Note to Users Please contact me or my team at the following email addresses - =over 4 =item B or B =back and let us know of any and all bugs, issues, problems, questions as well as suggestions for improvements to both the documentation and module itself. We will make every effort to get back to you quickly. Update the module from CPAN *often* - as we anticipate adding documentation and fixing bugs and making improvements often. Brian Kelly, March 9, 2016 =head1 License This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. =head1 Shell Synopsis - simple "Hello World" =over 4 =item use Net::FullAuto; $localhost=connect_shell(); ($stdout,$stderr,$exitcode)=$localhost->cmd("echo 'Hello World'"); print $stdout; =back =head1 SSH & SFTP Combined Synopsis =over 4 =item use Net::FullAuto; my $ip_or_hostname = $ARGV[0] || 'localhost'; my $username = $ARGV[1] || getlogin || getpwuid($<); my $identity_file = $ARGV[2] || ''; # required unless password or # or key-based login my $password = $ARGV[3] || ''; # required unless identity file # or key-based login my $remote_host_block={ Label => 'Remote Host', Hostname => $ip_or_hostname, Login => $username, IdentityFile => $identity_file, # can leave out if password or # or key-based login Password => $password, # can leave out if identity file # or key-based login # password is CLEAR TEXT, which # is poor security. Consider # IdentityFile or key-based login #log => 1, #debug => 1, #quiet => 1, }; my ($remote_host_handle,$error)=('',''); # Define and scope variables ($remote_host_handle,$error)=connect_secure($remote_host_block); die "Connect_SSH ERROR!: $error\n" if $error; my ($stdout,$stderr,$exitcode)=('','',''); # Define and scope variables ($stdout,$stderr,$exitcode)= $remote_host_handle->cmd('hostname'); # Run 'hostname' command in die $stderr if $stderr; # remote command line environment print "REMOTE HOSTNAME IS: $stdout\n"; ($stdout,$stderr,$exitcode)= $remote_host_handle->cwd('/'); # Change working directory to the die $stderr if $stderr; # root of the remote host ($stdout,$stderr,$exitcode)=$remote_host_handle->cmd('pwd'); die $stderr if $stderr; print "REMOTE HOST CURRENT DIRECTORY VIA SSH IS: $stdout\n"; ($stdout,$stderr,$exitcode)=$remote_host_handle->cwd('/'); die $stderr if $stderr; my @stdout=$remote_host_handle->sftp('pwd'); print "REMOTE HOST CURRENT DIRECTORY VIA SFTP IS: $stdout[1]<==\n"; $remote_host_handle->lcd('~'); @stdout=$remote_host_handle->sftp('!pwd'); print "LOCAL HOST CURRENT DIRECTORY VIA SFTP IS: $stdout[1]<==\n"; #$remote_host_handle->close(); # Use this -OR- cleanup method cleanup; # Use this routine for faster cleanup =back =head1 SSH Synopsis =over 4 =item use Net::FullAuto; my $ip_or_hostname = $ARGV[0] || 'localhost'; my $username = $ARGV[1] || getlogin || getpwuid($<); my $identity_file = $ARGV[2] || ''; # required unless password or # or key-based login my $password = $ARGV[3] || ''; # required unless identity file # or key-based login my $remote_host_block={ Label => 'Remote Host', Hostname => $ip_or_hostname, Login => $username, IdentityFile => $identity_file, # can leave out if password or # or key-based login Password => $password, # can leave out if identity file # or key-based login # password is CLEAR TEXT, which # is poor security. Consider # IdentityFile or key-based login #log => 1, #debug => 1, #quiet => 1, }; my ($remote_host_handle,$error)=('',''); # Define and scope variables ($remote_host_handle,$error)=connect_ssh($remote_host_block); die "Connect_SSH ERROR!: $error\n" if $error; my ($stdout,$stderr,$exitcode)=('','',''); # Define and scope variables ($stdout,$stderr,$exitcode)= $remote_host_handle->cmd('hostname'); # Run 'hostname' command in die $stderr if $stderr; # remote command line environment print "REMOTE HOSTNAME IS: $stdout\n"; ($stdout,$stderr,$exitcode)= $remote_host_handle->cwd('/'); # Change working directory to the die $stderr if $stderr; # root of the remote host ($stdout,$stderr,$exitcode)=$remote_host_handle->cmd('pwd'); die $stderr if $stderr; print "CURRENT DIRECTORY IS: $stdout\n"; #$remote_host_handle->close(); # Use this -OR- cleanup method cleanup; # Use this routine for faster cleanup =back =head1 SFTP Synopsis =over 4 =item use Net::FullAuto; my $ip_or_hostname = $ARGV[0] || 'localhost'; my $username = $ARGV[1] || getlogin || getpwuid($<); my $identity_file = $ARGV[2] || ''; # required unless password or # or key-based login my $password = $ARGV[3] || ''; # required unless identity file # or key-based login my $remote_host_block={ Label => 'Remote Host', HostName => $ip_or_hostname, LoginID => $username, IdentityFile => $identity_file, # can leave out if password or # or key-based login Password => $password, # can leave out if identity file # or key-based login # password is CLEAR TEXT, which # is poor security. Consider # IdentityFile or key-based login #log => 1, #debug => 1, #quiet => 1, }; my ($remote_host_handle,$error)=connect_sftp($remote_host_block); die "Connect_SFTP ERROR!: $error\n" if $error; my ($stdout,$stderr)=('','',''); # Define and scope variables my @stdout=$remote_host_handle->cmd('pwd'); print "REMOTE DIRECTORY IS: @stdout\n"; ($stdout,$stderr)=$remote_host_handle->cwd('/'); die $stderr if $stderr; @stdout=$remote_host_handle->cmd('pwd'); print "CURRENT DIRECTORY IS: @stdout\n"; #$remote_host_handle->close(); # Use this -OR- cleanup method cleanup; # Use this routine for faster cleanup =back =head1 FullAuto Framework (Coming Soon) Synopsis (Beta/Experimental) =over 4 The FullAuto Framework utilizes the C command line utility. Limited functionality is already available, and is documented in various sections below. Only the "Framework" is experimental. FullAuto itself is fully released. The rest of the documentation describes fully released FullAuto functionality. See the L section below for more information on the FullAuto Framework and other features currently in development. You can preview elements of the FullAuto Framework with this command: fa --new-user Using Term::Menus, the FullAuto "new user experience" demonstrates how a command environment solution (which is or should be the domain of most distributed workload automation) can be I, without the need, overhead and cost of a web (or any other GUI) infrastructure. Self-documenting solutions are particularly needed for automated processes, because when they work I, an automated solution can go months or even years without a human examining it in detail - often long after the orginal implementers have left the organization. This is the first "page" of the "new user experience": ___ _ _ _ _ | __| _| | | /_\ _ _| |_ | ( /_ /_ _ _ | _| || | | |/ _ \ || | _/ | \ |/|/(-(( ()//)(- To |_| \_,_|_|_/_/ \_\_,_|\__\___/c username Items with the arrow character > are the current selection, Just press ENTER or Scroll with UP and DOWN arrow keys. You can also type the number of your selection, and then press ENTER to activate your selection. It appears that username is new to FullAuto, for there is no FullAuto Setup for this user. > 1 Getting Started (quickly) with FullAuto. Recommended for beginners. 2 Setup User username (Advanced Users) 3 Continue with Login (No setup for username) & Do Not Show this Screen Again 4 Continue with Login (No setup for username) (Press [F1] for HELP) ([ESC] to Quit) PLEASE ENTER A CHOICE: =back =head1 Description CS< > (aka C) is a Perl module and workload automation functionality that transforms Perl into a true multi-host scripting language. It accomplishes this with multiple B<*PERSISTENT*> SSH and SFTP connections to multiple hosts simultaneously. With FullAuto entire hosts are encapsulated in a single filehandle. Think of each filehandle as an always available SSH client (like PuTTY) and SFTP client (like WinSCP) that are available I to the script. The importance of I connections when attempting to programmatically control remote hosts cannot be over stated. Essentially, it means that FullAuto can "fully" automate just about B. To see FullAuto in action, please download and explore the "Self Service Demonstration" at L. The demo contains an embedded YouTube video (L) explaining and showing the entire automated process of setting up a complex multi-host infrastructure in the Amazon EC2 Cloud. After watching or while watching the video, you can run the demo and standup your own cloud infrastructure in just a few minutes. The Hadoop demo is particularly interesting and timely given the recent explosion of BIG DATA and the need to access it more powerfully. The Hadoop demo utilizes a special FullAuto L" that stands up a complete 4 node/server cluster in the Amazon EC2 Cloud. Every element of the build and stand up is automated including using the EC2 API to launch servers, connecting to all 4 servers automatically with SSH & SFTP, downloading and compiling Hadoop source code from L, downloading and installing Java and all other dependencies, and then cross-configuring all 4 nodes with discovered IP addresses and other information that was unknown at the beginning of the standup - and finally starting the cluster and launching an admin web portal. Imagine a scripting language that can essentially turn an entire network of computers into a truly interactive collective. This is precisely what FullAuto does. FullAuto utilizesS< >CS< >andS< >CS< >(can also useS< >CS< >andS< >C, though for security reasons, this is NOT recommended) to bring the command environments of any number of remote computers (Operating System of remote computer does not matter), together in one convenient scripting space. With FullAuto, you write code once, on one computer, and have it execute on multiple computers simultaneously, in an interactive dynamic fashion, as if the many computers were truly one. How is FullAuto different from programs like Chef (http://www.chef.io) and Puppet (http://www.puppetlabs.com) and Ansible (http://www.ansible.com) and Salt (http://www.saltstack.com)? All of which assert the same ability and functionality? Chef and Puppet and Salt require the use of agents on remote hosts. FullAuto has no such dependency, as it is agent-less. It works against any SSH server implementation on any operating system. Ansible claims to be "agent-less" but actually has a dependency on the Python scripting language being available on the remote host, as well as requiring that the OpenSSH daemon on remote nodes be configured to utilize the ControlPersist feature. FullAuto has no such dependency (FullAuto does not even require Perl on the remote nodes), and if any manual terminal program or utility can connect to a device viaS< >CS< >orS< >CS< >orS< >CS< >or evenS< >CS< >orS< >C,S< >FullAuto can connect as well - persistently. FullAuto goes beyond these packages in its unique ability to L multiple hosts with the same persistent connection capability. This means, without agents or any special configuration, FullAuto can L connect through any number of hosts and navigate multiple network segments to get you to the host and data you need - in REAL time! Real time interactive command channels and data feeds are the next "big thing", but till now have been incredibly difficult to setup, maintain and keep secure (not to mention "expensive"). With FullAuto, it is now possible for a single ssh process to proxy out through a firewall to a box in the DMZ, from that host go any distance across the internet to another ssh host in another organization's DMZ, proxy through that host and through the firewall, and continue navigating proxies until the process arrives at the host, functionality and data it needs. For additional security, the destination organization can also use FullAuto to host a real time "SSH Service API" (similar to web services) and allow a distant process controlled and precise access to hosts and data just as is provided with web services - without the burden of certificates, https, tokens, etc. - and with better performance (due to the simplicity and direct connect capability of FullAuto's architecture). Web services are still predominantly "stateless" due to the architecture of the http protocol. FullAuto is state-FULL, insuring the most direct access to remote host functionality and data imaginable - regardless of application. Moreover, because FullAuto proxy connections are lightweight, proxy hosts in DMZ environments can do double duty as "honey pots" - which themselves can be stood up, fully configured and fully managed automatically by FullAuto. (L). FullAuto can be run by a user in a Menu driven, interactive mode (using the L module - also written by Brian Kelly), or via UNIX or Linux C or Windows Scheduler or Cygwin C in a fully automated fashion. Example: A user needs to pull data from a database, put it in a text file, zip and encrypt it, and then transfer that file to another computer on the other side of the world via the internet - in one-step. Assume FullAuto is installed on computer one, the database is on computer two, and the remote computer in Japan is computer three. When the user starts the script using C, FullAuto will connect via C and C (simultaneously) to computer two, and via C to computer three. Using a sql command utility on computer two, data can be extracted and piped to a text file on computer two. Then, FullAuto will run the command for a C utility over C on computer two to compress the file. Next (assume the encryption software is on computer one) FullAuto will transfer this file to computer one, where it can be encrypted with licensed encryption software, and then finally, the encrypted file can be transferred to computer three via C. Email and pager software can be used for automated notification as well. Example: The same process above needs to run at 2:00am unattended. A script using FullAuto can be run via C (or any other scheduler) to perform the same actions above without user involvement. Each individual command run on a remote computer returns to FullAuto STDOUT (output) and STDERR (error messages) and command exit codes. With these features, users and programmers can write code to essentially trap remote errors "locally" and respond with any number of error recovery approaches. Everything from sending an e-mail, to re-running the command, to switching remote computers and much more is available as error handling options. The only limits are the skills and ingenuity of the programmers and administrators using FullAuto. If FullAuto loses a connection to a remote host, automatic attempts will be made to re-connect seamlessly - with errors reported when the configured maximum numbers of attempts fail. Connecting to a remote host is as simple as: ------------------------------------------------------------------------ use Net::FullAuto; my $remote_host_info={ Label => 'Remote Host', Hostname => $ip_or_hostname, Login => $username, IdentityFile => $identity_file, # can leave out if password or # or key-based login is used # Password => $password, # can leave out if identity file # or key-based login is used }; my $remote_host_handle=connect_ssh($remote_host_info); ------------------------------------------------------------------------ Commands also are easy: ------------------------------------------------------------------------ my ($stdout,$stderr,$exitcode)=$remote_host_handle->cmd('ls -l'); ------------------------------------------------------------------------ In addition, no cleanup is necessary - FullAuto handles cleanup I. FullAuto uses C and C for communication across hosts and devices. FullAuto connections can be configured to use password-less key exchange. =head1 Reasons to Use this Module To do everything you could do with other workload automation packages like Chef, Puppet, Anisble and Salt without the cost, overhead and resource requirements of those solutions. To go beyond those packages and set up real-time ssh proxy-chained interactive command channels and data feeds. To do L via sftp or insecure ftp without having to impose requirements on owners of remote host servers. To have an entire workload automation encapsulated in a single L that often is so tiny; it can easily be attached to an email. You need a solution that is as easy to install as C. You want the entire CPAN available for use in your L. You want the true strengths of Perl and the Perl Community and features like Perl's unsurpassed regular expression functionality readily available. You want the flexibility of a serial scripting language, and the option to use modern OO programming with Moose. A solution that can work equally well on both UNIX/Linux and Windows operating systems (FullAuto works on Windows within the Cygwin Linux layer for Windows environment). FullAuto is the SIMPLEST and most direct path to Full Automation (hence the name). That path is to make full use of trusted connectivity components already in widespread use on billions of devices the world over. SSH and SFTP are literally on every UNIX and Linux host in the world - and are both easily added to MS Windows. SSH and SFTP are used to connect to multiple network devices such as routers and switches. SSH and SFTP are a widely available means to connect to the Mainframe. All we EVER needed was an automation solution that simply utilized this widespread access architecture already in place - AS IS, without requiring any special features or configuration. That solution is now a reality - and its name is B. =head1 Connect Methods =head2 B<%connection_info> - hash to pass connection information to the following connect_ methods. =over 4 =item %connection_info=( Label => '', Hostname => '', # Optional - need Hostname -or- IP Address IP => '', Login => '', Use => ', # When both Hostname and IP are listed, # use the specified first IdentityFile => '', # Optional - RECOMMENDED (most secure) Password => '', # Optional - *NOT* Recommended Log => 1 | 0, # Optional - Log output to FullAuto log Debug => 1 | 0, # Optional - Display debug info in output Quiet => 1 | 0, # Optional - Suppress output Timeout => , # Optional - Default is 90 seconds. Use to extend # time allowed to establish a connection Proxy => <\%proxy_connection_info>, # Optional - use other host as a # Proxy ); =back =head3 Label =over 4 =item C