SFTP Deployer

Script di automazione per l'upload su server multipli tramite sFTP.
PHP, JSON - 2018

JSON Config file

Un estratto del file di configurazione che contiene le pagine di cui aggiungere i metatag definiti.

                
                {
                    "servers":
                    {
                        "<ip address 1>":
                        {
                            "name": "Server 1 name"
                            ,"port" : 22
                            ,"remote_base_dir" : "/var/www/..."
                            ,"username" : "username"
                            ,"password" : "password"
                        },
                        "<ip address 2>":
                        {
                            "name": "Server 2 name"
                            ,"port" : 22
                            ,"remote_base_dir" : "/var/www/..."
                            ,"username" : "username"
                            ,"password" : "password"
                        }
                    },

                    "folders_to_upload":
                    [
                        "folder1"
                        ,"folder2"
                        ,"public"
                    ],
                    "folders_to_create":
                    {
                        "public/subfolder1":"0775"
                        ,"public/subfolder2":"0775"
                    },
                    "folders_to_exclude":
                    [
                        "folder1/subfolder1"
                        ,"folder1/subfolder2/subsubfolder1"
                    ],
                    "files_to_exclude":
                    [
                        "folder1/file1.html"
                        ,".gitignore"
                    ]
                }
                
                

Login

La funzione autentica al server tramite ssh e restituisce l'handle sftp per poter utilizzare i comandi sFTP

                
                /*
                 * $sftp = login('192.168.1.22', 22, 'username', 'password');
                 */
                function login($host, $port, $username, $password)
                {
                    $connection = ssh2_connect($host, $port);
                    if (!$connection)
                    {
                        echo "Could not connect to $host on port $port.";
                        return false;
                    }

                    if (! ssh2_auth_password($connection, $username, $password))
                    {
                        echo "Could not authenticate with username: $username";
                        return false;
                    }
                    $sftp = ssh2_sftp($connection);
                    if (! $sftp)
                    {
                        echo "Could not initialize SFTP subsystem";
                        return false;
                    }
                    return $sftp;
                }
                
                

Upload single file

La funzione effettua l'upload di un file

                
                /*
                 * $sftp = ...;
                 * uploadFile($sftp, '/var/www/html/public/index.html', 'var/www/site_1/public/index.html');
                 */
                function uploadFile(&$sftp, $local_file, $remote_file)
                {
                    if (!file_exists($local_file)) return false;

                    $stream = @fopen("ssh2.sftp://$sftp$remote_file", 'w');

                    if (!$stream)
                    {
                        if (!@mkdir("ssh2.sftp://$sftp".dirname($remote_file), 0775, true))
                        {
                            echo "Could not create folder: ".dirname($remote_file);
                            return false;
                        }
                        $stream = @fopen("ssh2.sftp://$sftp$remote_file", 'w');
                    }
                    if (! $stream)
                    {
                        echo "Could not open file: $remote_file";
                        return false;
                    }

                    $data_to_send = @file_get_contents($local_file);
                    if ($data_to_send === false)
                    {
                        echo "Could not open local file: $local_file.";
                        return false;
                    }

                    if (@fwrite($stream, $data_to_send) === false)
                    {
                        echo "Could not send data from file: $local_file.";
                        return false;
                    }

                    @fclose($stream);
                    return true;
                }
                
                

Create remote folder

La funzione permette di creare una cartella sul server remoto

                

                /*
                 * $sftp = ...;
                 * createFolder($sftp, 'public/resources','0775');
                 */
                function createFolder(&$sftp, $folder, $mode)
                {
                    if (file_exists("ssh2.sftp://$sftp$folder"))
                    {
                        return true;
                    }
                    if (!@mkdir("ssh2.sftp://$sftp$folder", intval($mode, 8), true))
                    {
                        echo "Could not create folder: $folder";
                        return false;
                    }
                    return true;
                }
                
                

Upload entire folder

La funzione permette di effettuare l'upload di una cartella. E' possibile specificare i nomi delle cartelle da escludere ed i file

                
                /*
                 * $sftp = ...;
                 * uploadFolder(  $sftp
                                , '/var/www/html'
                                , '/var/www/site_1'
                                , 'public'
                                , array(
                                    'public/private_subfolder'
                                )
                                , array(
                                    'public/private_file.txt'
                                )
                            );
                 */
                function uploadFolder(&$sftp, $local_base_folder, $remote_base_folder, $folder_to_upload, $exclude_folders=null, $exclude_files=null)
                {
                    if (substr($local_base_folder, strlen($local_base_folder) - 1, 1) != '/')
                    {
                        $local_base_folder .= '/';
                    }
                    if (substr($folder_to_upload, strlen($folder_to_upload) - 1, 1) != '/')
                    {
                        $folder_to_upload .= '/';
                    }


                    $files = glob($local_base_folder.$folder_to_upload.'{,.}*', GLOB_BRACE);
                    
                    foreach ($files as $file)
                    {
                        if ($file == $local_base_folder.$folder_to_upload.'.') continue;
                        if ($file == $local_base_folder.$folder_to_upload.'..') continue;
                        if (is_dir($file))
                        {
                            $folder_must_be_excluded = false;

                            if ($exclude_folders)
                            {
                                for($i=0;$i<count($exclude_folders);$i++)
                                {
                                    if ($local_base_folder.$exclude_folders[$i] == $file)
                                    {
                                        $folder_must_be_excluded = true;
                                        break;
                                    }
                                }
                            }

                            if (!$folder_must_be_excluded)
                            {
                                uploadFolder($sftp, $local_base_folder, $remote_base_folder, $folder_to_upload.basename($file), $exclude_folders, $exclude_files);
                            }
                        }
                        else
                        {
                            $file_must_be_excluded = false;
                            for($i=0;$i<count($exclude_files);$i++)
                            {
                                if ($local_base_folder.$exclude_files[$i] == $file)
                                {
                                    $file_must_be_excluded = true;
                                    break;
                                }
                            }

                            if (!$file_must_be_excluded)
                            {
                                uploadFile($sftp, $file, $remote_base_folder.$folder_to_upload.basename($file), $folder_to_upload);
                            }
                        }
                    }
                }


                
                

Esempio

                

				function do_deploy_on_server($ip
							, $server_name
							, $port
							, $uname
							, $password
							, $remote_base_dir
							, $local_basedir
							, $folders_to_create
							, $folders_to_upload
							, $folders_to_exclude
							, $files_to_exclude)
				{
				    try
				    {
				        $start_tstamp = time();
				        
				        $sftp = login($ip, $port, $uname, $password);
				        
				        foreach($folders_to_create as $folder_to_create => $mode)
				        {
				            createFolder($sftp, $remote_base_dir.$folder_to_create, $mode);
				        }
				        
				        for($i=0;$i<count($folders_to_upload);$i++)
				        {
				            uploadFolder($sftp, $local_basedir
				                , $remote_base_dir
				                , $folders_to_upload[$i]
				                , $folders_to_exclude
				                , $files_to_exclude
				            );
				        }
				        
				        $dur_tot = time() - $start_tstamp;
				        $mins = intval(($dur_tot) / (60), 10);
				        $hrs = 0;
				        if ($mins >= 60) $hrs = intval($mins / 60, 10);
				        $mins = $mins - ($hrs*60);
				        $secs = $dur_tot - ($mins*60) - ($hrs*3600);
				        echo "\r\nELAPSED TIME:\t\t".$hrs.'h '.$mins.'m '.$secs.'s';
				        echo "\r\nSTART:\t\t\t".date('d M Y H:i:s', $start_tstamp).' >> ('.$start_tstamp.")";
				        echo "\r\nEND:\t\t\t".date('d M Y H:i:s').' >> ('.time().")\r\n";
				    }
				    catch (Exception $e)
				    {
				        echo "!!! ".$e->getMessage() . "\r\n";
				    }
				}


				// ==================================================================
				// MAIN

				...
				$config = json_decode(file_get_contents('config.json'), true);

				$servers = $config['servers'];

				$folders_to_create = $config['folders_to_create'];
				$folders_to_upload = $config['folders_to_upload'];
				$folders_to_exclude = $config['folders_to_exclude'];
				$files_to_exclude = $config['files_to_exclude'];

				foreach ($servers as $ip => $values)
				{
					do_deploy_on_server($ip
						, $values['name']
						, $values['port']
						, $values['username']
						, $values['password']
						, $values['remote_base_dir']
						, $local_basedir
						, $folders_to_create
						, $folders_to_upload
						, $folders_to_exclude
						, $files_to_exclude);
				}