cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1714
Views
0
Helpful
2
Replies

FMC 1000 to FMC 4500 migration

rocky88
Level 1
Level 1

Hi Everyone, Is the FMC migration possible from FMC 1000 to FMC 4500 with both models running 6.5.0 and then running the migration script? Has anyone tried this or is it only applicable to x600 series FMCs? Any idea on this.

2 Replies 2

Marvin Rhoads
Hall of Fame
Hall of Fame

The guide says it's only supported for target platforms of 1600/2600/4600 (in the hardware category anyway).

https://www.cisco.com/c/en/us/td/docs/security/firepower/fmc_model_migration/b_FMC_Model_Migration_Guide/about_fmc_model_migration.html#id_111597

The script:

https://www.cisco.com/c/en/us/td/docs/security/firepower/fmc_model_migration/b_FMC_Model_Migration_Guide/migrate_your_fmc.html#id_111629

...does seem to have some checking built-in:

root@fmc:/var/sf/bin# cat sf-migration.pl 
#!/usr/bin/perl

use warnings;

use SF;
use SF::Types;
use FlyLoader;
use Data::Dumper;
use POSIX ":sys_wait_h";
use Sys::Syslog;
use SF::System;
use SF::Auth;
use SF::Permission;
use Passwd::Linux;
use SF::CLI;
use Error qw(:try);
my $MODULE_NAME = "sf-migration";

my $storage = 'LOCAL';
my $tarfile;

my $migration_confirm = '/tmp/migrationConfirmation.txt';
my $tmpfile = SF::Reloc::RelocateFilename("/var/log/tmp.log");

my ( $isValidMigrationPath, $SOURCE_MODEL_ID, $TARGET_MODEL_ID );

#Signal to handle any interruption during the coarse of action
$SIG{INT} = sub {
    if (-e $migration_confirm) {
        system("rm -rf $migration_confirm");   
    }
    system("rm -rf $tmpfile");
    print("\nRestore Interrupted\n");
    exit(1);
};

my @args = map { split ( / / ) } @ARGV;
$storage = shift @args;
my $logfile = SF::Reloc::RelocateFilename("/var/log/restore.log");
system("rm -rf $migration_confirm");


# get the tarfile from the remote location
if($storage eq 'REMOTE'){
    $tarfile = getTarfileFromRemote(\@args);
    if(!defined $tarfile){
        print STDERR "Cannot get the backup file from remote location";
        loginfo("Cannot get the backup file from remote location");
        exit(1);
    }
}else{
    $tarfile = $storage; #Here if REMOTE is not specified, it is assumed as LOCAL and $storage will contain the file name
    ( $isValidMigrationPath, $SOURCE_MODEL_ID, $TARGET_MODEL_ID ) = SF::BackupRestore::isValidMigrationPath($tarfile);
    }

my $pid = fork;

if ($pid) {
    $| = 1;
    while (waitpid($pid, &WNOHANG) != $pid) {
        # check statusproc  from time to time 
        if(  -e "/tmp/migrationConfirmation.txt") {  # the child has ended it's task
            print(" .");
            sleep(2);
        }
    }
} else {
    if(! -e $tarfile){
        print("\n\nThe backup file does not exist in /var/sf/backup\n\n");
        exit(1);
    }
    if($isValidMigrationPath == 0) {
        exit(1);
    }
    print "\n\n\n ******************WARNING: Running this script will modify Management IP Address of this Firepower Management Center using configurations from backup file. Make sure that Firepower Management Center from where backup was taken, is disconnected from network to avoid IP conflict.*********************\n\n\n";
    print "Are you sure you want to continue (Y/N)";
    my $choice = <STDIN> ;
    if ($choice =~ m/^[Y]$/i) {
            print("Migrating device . . . . . . . . . . . . . . . . . . . . . . . . . .");
            loginfo("Migrating device . . . . . . . . . . . . . . . . . . . . . . . . . .");
            SF::System::touch(
            dirname  => '/tmp',
            filename => 'migrationConfirmation.txt'
            );
            exec("/usr/local/sf/bin/sf-restore-backup.pl \"$tarfile\" MIGRATE_MODEL &> $logfile");
            exit(1); #this exit(1) call is only performed, if the above exec call fails
    } else {
        print "Exiting the script..\n";
    }
}
printLogfile();

sub printLogfile
{
    if(-e $tmpfile) {
        if (open(my $fh, '<:encoding(UTF-8)', $tmpfile)) {
            while (my $row = <$fh>) {
                chomp $row;
                print "$row\n";
            }
        }
    }
}

sub getTarfileFromRemote
{
    #Verify whether args contains hostname, username, directory, and filename
    my $backup_path = "/var/sf/backup/";
    my $isIpv6 = undef;
    if ( defined $args[0] && defined $args[1] && defined $args[2] && defined $args[3]){
        my $hostname = $args[0];
        my $username = $args[1];
        my $directory = $args[2];
        my $filename = $args[3];
        my $new_file = $hostname . "_" . $filename;
        my $ipv6_hostname = undef;

        # Validate ipv6 Address, 
        if ( index ( $hostname, ":") != -1 ) {
            loginfo ( "Found ipv6 address in hostname" );
            my $ipv6_protocol = 'ipv6';
            $isIpv6 = SF::Types::is_valid('ip', $hostname, {$ipv6_protocol => 1});
            if (  defined $isIpv6 ) {
                $ipv6_hostname = "[". $hostname . "]";
                loginfo ( "new hostname = $ipv6_hostname" );
            } 
        }
        
        $new_file = $backup_path . $new_file;
        my $full_path = $directory . "/" . $filename;
        require Net::SCP::Expect;
        my $current_pw=getPassword();
        $hostname = $hostname . ":" . $directory . "/" . $filename;
        my $scp = Net::SCP::Expect->new( host=>$hostname,
                                      user=>$username,
                                      password=>$current_pw,
                                      auto_yes=>1, option=>"UserKnownHostsFile=/dev/null",
                                      timeout_auto=>15);
        try
        {
            if (defined $hostname) {
                if ( defined $isIpv6 ) {
                    # Block validates and execute if hostname is ipv6
                    loginfo (" Calling with system scp ");
                    
                    my @scp_cmd = ("/usr/bin/scp", "-o CheckHostIP=no", "-o StrictHostKeyChecking=no", "-o UserKnownHostsFile=/dev/null",
                    $username . '@' . $ipv6_hostname . ':' . $full_path, $backup_path );
                    loginfo ( "scp command = @scp_cmd " );
                    my $status = system(@scp_cmd);
                    if ($status != 0) 
                    {
                        loginfo ( " scp file pull error code : $status " );
                        return;
                    }
                    my $old_ipv6_file = $backup_path . $filename;
                    my $new_ipv6_file = $new_file;
                    loginfo (" Old file = $old_ipv6_file New File = $new_ipv6_file");
                    $status = system ("mv $old_ipv6_file $new_ipv6_file");
                    return $new_ipv6_file;
                } else {
                    # Block validates and execute if hostname is ipv4
                    $scp->scp($hostname, $new_file);
                    return $new_file;
                }
            }
        }
        catch Error with
        {
            my $E = shift();
            if($E =~ "Bad password") {
                print("\nError in copying backup file from remote location; Bad username/password\n");
            }elsif($E =~ "No such file or directory") {
                print("\nError in copying backup file from remote location; $full_path Invalid file or directory\n");
            }elsif ($E =~ "timed out") {
                print("\nError in copying backup file from remote location; Connection to timed out\n");
            }else{     
                print("\n$E\n");
                print("\nError in copying backup file from remote location\n");
            }
            exit(1);
        };
    }else{
        print "Enter details in the following sequence and try again : <Hostname>, <Username>, <Directory>, <Filename>";
        loginfo("Enter details in the following sequence and try again : <Hostname>, <Username>, <Directory>, <Filename>");
        exit(1);
    }
}

sub getPassword
{
    my $pw;
    print "Enter SCP password: ";
    SF::CLI::stty_echo(0);
    $pw = <STDIN>;
    chomp($pw);
    SF::CLI::stty_echo(1);
    print "\n";
    return $pw;
}


sub loginfo
{
    my ( $msg ) = @_;
    open(my $fh, '>>', $logfile);
    print $fh (localtime)." $msg\n";
    close $fh;
}
root@fmc

@Marvin Rhoads , Thank you. That was helpful, I had a look into the script and it seems it does some checking. The guide does say we can do from a lower model to higher model but the table says the target module should be x600.

Review Cisco Networking for a $25 gift card