Beispiel #1
0
def main():
    """
    Main execution routine

    :return: None
    """
    creds = Credentials('apic')
    creds.add_argument('--tenant', help='The name of Tenant')
    creds.add_argument('--app', help='The name of ApplicationProfile')
    creds.add_argument('--bd', help='The name of BridgeDomain')
    creds.add_argument('--epg', help='The name of EPG')
    creds.add_argument('--json',
                       const='false',
                       nargs='?',
                       help='Json output only')

    args = creds.get()
    session = Session(args.url, args.login, args.password)
    session.login()

    tenant = Tenant(args.tenant)
    app = AppProfile(args.app, tenant)
    bd = BridgeDomain(args.bd, tenant)
    epg = EPG(args.epg, app)
    epg.add_bd(bd)

    if args.json:
        print(tenant.get_json())
    else:
        resp = session.push_to_apic(tenant.get_url(), tenant.get_json())

        if not resp.ok:
            print('%% Error: Could not push configuration to APIC')
            print(resp.text)
def get_interface_stats_from_nodes():
    """
    Main execution routine

    :return: None
    """
    description = ('get_stats - A program to fetch statistics from an ACI '
                   'Fabric.')
    creds = Credentials('apic', description)
    creds.add_argument('-f', '--format', required=False, default='text',
                       help='Specify output format [csv, text]')
    creds.add_argument('-i', '--interval', required=False, default='15min',
                       help='Specify the aggregation interval')
    creds.add_argument('-n', '--node_type', required=False, default='spine',
                       help='Specify the type of node [spine, leaf, both]')
    creds.add_argument('-t', '--threshold', required=False, default=60,
                       type=int,
                       help='Specify the threshold for printing usage.')
    creds.add_argument('-v', '--verbose', action='count',
                       help='Specify verbosity of debug output.')

    args = creds.get()
    if args.format not in ['text', 'csv']:
        print >> sys.stderr, "Error: Unknown output format: '{}'".format(
            args.format)
        sys.exit(3)
    if args.interval not in ['5min', '15min', '1h', '1d', '1w', '1mo', '1qtr',
                             '1year']:
        print >> sys.stderr, "Error: Unknown interval '{}'".format(
            args.interval)
        sys.exit(4)
    if args.node_type in ['spine', 'leaf']:
        node_type = [args.node_type]
    elif args.node_type in ['both']:
        node_type = ['spine', 'leaf']
    else:
        print >> sys.stderr, "Error: Unknown node type: '{}'".format(
            args.node_type)
        sys.exit(5)
    if args.threshold > 100:
        threshold = 100
    elif args.threshold < 0:
        threshold = 0
    else:
        threshold = args.threshold

    # Login to APIC
    session = Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print('%% Could not login to APIC')
        sys.exit(0)

    statistics = Stats(session, args.format, args.verbose)
    statistics.get_int_traffic(node_type, args.interval, threshold)
Beispiel #3
0
def acilint():
    """
    Main execution routine

    :return: None
    """
    description = ('acilint - A static configuration analysis tool. '
                   'Checks can be individually disabled by generating'
                   ' and editing a configuration file.  If no config '
                   'file is given, all checks will be run.')
    creds = Credentials('apic', description)
    creds.add_argument('-c', '--configfile', type=argparse.FileType('r'))
    creds.add_argument('-g',
                       '--generateconfigfile',
                       type=argparse.FileType('w'))
    args = creds.get()

    if args.generateconfigfile:
        print 'Generating configuration file....'
        f = args.generateconfigfile
        f.write(('# acilint configuration file\n# Remove or comment out any '
                 'warnings or errors that you no longer wish to see\n'))
        methods = dir(Checker)
        for method in methods:
            if method.startswith(('warning_', 'critical_', 'error_')):
                f.write(method + '\n')
        f.close()
        sys.exit(0)

    methods = []
    if args.configfile:
        f = args.configfile
        for line in f:
            method = line.split('\n')[0]
            if method in dir(Checker) and method.startswith(
                ('warning_', 'error_', 'critical_')):
                methods.append(method)
        f.close()
    else:
        for method in dir(Checker):
            if method.startswith(('warning_', 'error_', 'critical_')):
                methods.append(method)

    if args.snapshotfiles:
        session = FakeSession(filenames=args.snapshotfiles)
    else:
        # Login to APIC
        session = Session(args.url, args.login, args.password)
        resp = session.login()
        if not resp.ok:
            print '%% Could not login to APIC'
            sys.exit(0)

    checker = Checker(session)
    checker.execute(methods)
def acilint():
    """
    Main execution routine

    :return: None
    """
    description = ('acilint - A static configuration analysis tool. '
                   'Checks can be individually disabled by generating'
                   ' and editing a configuration file.  If no config '
                   'file is given, all checks will be run.')
    creds = Credentials('apic', description)
    creds.add_argument('-c', '--configfile', type=argparse.FileType('r'))
    creds.add_argument('-g', '--generateconfigfile',
                       type=argparse.FileType('w'))
    args = creds.get()

    if args.generateconfigfile:
        print 'Generating configuration file....'
        f = args.generateconfigfile
        f.write(('# acilint configuration file\n# Remove or comment out any '
                 'warnings or errors that you no longer wish to see\n'))
        methods = dir(Checker)
        for method in methods:
            if method.startswith(('warning_', 'critical_', 'error_')):
                f.write(method + '\n')
        f.close()
        sys.exit(0)

    methods = []
    if args.configfile:
        f = args.configfile
        for line in f:
            method = line.split('\n')[0]
            if method in dir(Checker) and method.startswith(('warning_', 'error_', 'critical_')):
                methods.append(method)
        f.close()
    else:
        for method in dir(Checker):
            if method.startswith(('warning_', 'error_', 'critical_')):
                methods.append(method)

    if args.snapshotfiles:
        session = FakeSession(filenames=args.snapshotfiles)
    else:
        # Login to APIC
        session = Session(args.url, args.login, args.password)
        resp = session.login()
        if not resp.ok:
            print '%% Could not login to APIC'
            sys.exit(0)

    checker = Checker(session)
    checker.execute(methods)
Beispiel #5
0
def main():
    """
    Main execution routine

    :return: None
    """
    creds = Credentials('apic')
    creds.add_argument('--tenant', help='The name of Tenant')
    creds.add_argument('--vrf', help='The name of VRF')
    creds.add_argument('--bd', help='The name of BridgeDomain')
    creds.add_argument('--address', help='Subnet IPv4 Address')
    creds.add_argument('--scope', help='The scope of subnet ("public", "private", "shared", "public,shared", "private,shared", "shared,public", "shared,private")')
    creds.add_argument('--json', const='false', nargs='?', help='Json output only')

    args = creds.get()
    session = Session(args.url, args.login, args.password)
    session.login()

    tenant = Tenant(args.tenant)
    vrf = Context(args.vrf)
    bd = BridgeDomain(args.bd, tenant)
    bd.add_context(vrf)

    if args.address is None:
        bd.set_arp_flood('yes')
        bd.set_unicast_route('no')
    else:
        bd.set_arp_flood('no')
        bd.set_unicast_route('yes')

        subnet = Subnet('', bd)
        subnet.addr = args.address

        if args.scope is None:
            subnet.set_scope("private")
        else:
            subnet.set_scope(args.scope)

    if args.json:
        print(tenant.get_json())
    else:
        resp = session.push_to_apic(tenant.get_url(),
                                    tenant.get_json())

        if not resp.ok:
            print('%% Error: Could not push configuration to APIC')
            print(resp.text)
Beispiel #6
0
# Start of the execution
if __name__ == "__main__":

    items = {'left': {}, 'right': {}}

    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = 'APIC credentials'
    creds = Credentials('apic', description)
    creds.add_argument('-L', "--left", default=None, help='Object on the left')
    creds.add_argument('-R',
                       "--right",
                       default=None,
                       help='Object on the right')
    creds.add_argument('-t', "--type", default=None, help='Object type')
    args = creds.get()

    # Arg validation
    if args.right is None:
        fatal(
            "[E] Right object missing. Please pass it using --right <obj_name>"
        )
    if args.left is None:
        fatal(
            "[E] Left object missing. Please pass it using --left <obj_name>")
Beispiel #7
0
    def run():
        # Argument parsing. We use the ACI toolkit logic here, which tries to
        # retrieve credentials from the following places:
        # 1. Command line options
        # 2. Configuration file called credentials.py
        # 3. Environment variables
        # 4. Interactively querying the user
        # At the end, we should have an object args with all the necessary info.
        description = 'APIC credentials'
        creds = Credentials('apic', description)
        creds.add_argument('-d',
                           "--debug",
                           default=None,
                           help='Enable debug mode')
        creds.add_argument('-A',
                           "--address",
                           default=None,
                           help='Local IP address')
        creds.add_argument('-P',
                           "--port",
                           default=None,
                           help='Local Port for FTP connections')
        creds.add_argument('-K',
                           "--key",
                           default=None,
                           help='ACI encryption key')
        args = creds.get()

        # Print welcome banner
        ACIExport.print_banner()

        # Let's check if the user passed all relevant parameters
        if args.debug is not None:
            debug_enable()
        if args.address is None:
            # If the user didn't pass any IP address, let's figure out what IPs we
            # have configured locally. If it's only one, use it. Otherwise, ask
            # the user interactively to pick one
            candidates = {}
            for iface in netifaces.interfaces():
                for addr in netifaces.ifaddresses(iface):
                    addr_str = netifaces.ifaddresses(iface)[addr][0]['addr']
                    # Skip IPv6 addresses
                    if addr_str.count(":") > 0:
                        continue
                    # Skip localhost and unassigned addresses
                    elif addr_str == "0.0.0.0" or addr_str == "127.0.0.1":
                        continue
                    # Skip Microsoft auto-assigned addresses
                    elif addr_str.startswith("169.254."):
                        continue
                    else:
                        candidates[addr_str] = addr_str
            output(
                "Please indicate which local IP address should be used (enter its sequence number):"
            )
            for i in range(0, len(candidates)):
                print(" -> [%i] %s" % (i, candidates.keys()[i]))
            answer = -1
            while (not (answer >= 0 and answer < len(candidates))):
                try:
                    answer = int(input("$: "))
                except:
                    continue
            args.address = candidates[candidates.keys()[answer]]
            output("Address selected: %s" % args.address)
        if args.port is None:
            args.port = DEFAULT_FTP_PORT
        else:
            args.port = int(args.port)
        if args.key is None:
            args.key = DEFAULT_KEY

        # Now, we log into the APIC
        fabric = Fabric(args.url, args.login, args.password)
        fabric.connect()

        # Instance our FTP server
        ftplistener = FTPListener(addr=args.address, port=args.port)
        ftplistener.daemon = True
        ftplistener.start()

        # Nasty thing: sleep for 1 sec to give enough time to the FTP server to
        # initialize @todo: use decent concurrency control mechanisms
        time.sleep(1)

        # Push config to the fabric
        pols = ConfExportPolicy(addr=args.address,
                                port=args.port,
                                key=args.key)
        fabric.push_to_apic(pols)

        output(
            "Waiting for the ACI fabric to send its configuration export file..."
        )
        while g_do_exit is False:
            time.sleep(1)

        output("File '%s' was successfully received. Closing..." % g_recv_file)

        output("Please make a note of the encryption key: '%s'" % args.key)

        # Finally, stop the server and quit
        ftplistener.stop()

        return True
                output("%s:%s was %s" % (key, obj[key]['attributes']['dn'], obj[key]['attributes']['status'])  )


# Start of the execution
if __name__ == "__main__":

    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = 'APIC credentials'
    creds = Credentials('apic', description)
    creds.add_argument('-d', "--debug", default=None, help='Enable Debug mode')
    args = creds.get()
    
    # Process all relevant command-line parameters and print our welcome banner
    if args.debug is not None:
        debug_enable()
    print_banner()
    
    # Now, we log into the APIC
    session = Session(args.url, args.login, args.password)
    response = session.login()
    if response.ok is False:
        fatal(response.content)
    else:
        output("Successfully connected to %s" % args.url)
Beispiel #9
0
    output("           == Bridge Domain Configuration Fetching Tool ==      \n")


# Start of the execution
if __name__ == "__main__":

    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = 'APIC credentials'
    creds = Credentials('apic', description)
    creds.add_argument('-i', "--input", default=None, help='Input file')
    creds.add_argument('-c', "--commit", default=None, help='Make changes effective')
    creds.add_argument('-r', "--remove", default=None, help='Remove existing BD subnets')
    creds.add_argument('-d', "--debug", default=None, help='Enable Debug mode')
    args = creds.get()
    
    # Let's check if the user passed all relevant parameters:
    # 1. Input file (mandatory)
    if args.input is None:
        fatal("[E] Input filename missing. Please pass it using --output <filename>")
    # 2. Enable debug output (default: No)
    if args.debug is not None:
        debug_enable()
    # 3. Remove existing BD gayeways (default: No)
    if args.remove is not None and args.remove.lower() in ["y", "yes", "true"]:
        args.remove=True
Beispiel #10
0
                                         obj[key]['attributes']['status']))


# Start of the execution
if __name__ == "__main__":

    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = 'APIC credentials'
    creds = Credentials('apic', description)
    creds.add_argument('-d', "--debug", default=None, help='Enable Debug mode')
    args = creds.get()

    # Process all relevant command-line parameters and print our welcome banner
    if args.debug is not None:
        debug_enable()
    print_banner()

    # Now, we log into the APIC
    session = Session(args.url, args.login, args.password)
    response = session.login()
    if response.ok is False:
        fatal(response.content)
    else:
        output("Successfully connected to %s" % args.url)
Beispiel #11
0
    output("         == Bridge Domain GW Configuration Fetching Tool ==     \n")


# Start of the execution
if __name__ == "__main__":

    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = 'APIC credentials'
    creds = Credentials('apic', description)
    creds.add_argument('-o', "--output", default=None, help='Output file')
    creds.add_argument('-d', "--debug", default=None, help='Enable Debug mode')
    creds.add_argument('-f', "--filter", default=None, help='Retrieve only a single tenant')
    args = creds.get()
    
    # Let's check if the user passed all relevant parameters
    if args.output is None:
        fatal("[E] Output filename missing. Please pass it using --output <filename>")
    if args.debug is not None:
        debug_enable()

    # Welcome user with our cool banner ;-)
    print_banner()
    
    # Now, we log into the APIC
    session = Session(args.url, args.login, args.password)
Beispiel #12
0
    )


# Start of the execution
if __name__ == "__main__":

    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = 'APIC credentials'
    creds = Credentials('apic', description)
    creds.add_argument('-i', "--input", default=None, help='Input file')
    creds.add_argument('-d', "--debug", default=None, help='Input file')
    args = creds.get()

    # Let's check if the user passed all relevant parameters
    if args.input is None:
        fatal(
            "[E] Input filename missing. Please pass it using --input <filename>"
        )
    if args.debug is not None:
        debug_enable()

    # First of all, parse the input file.
    data = parse_spreadsheet(args.input)

    interfaces = []  # List of interfaces to push to the fabric
Beispiel #13
0
# Start of the execution
if __name__ == "__main__":

    items = {"left": {}, "right": {}}

    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = "APIC credentials"
    creds = Credentials("apic", description)
    creds.add_argument("-L", "--left", default=None, help="Object on the left")
    creds.add_argument("-R", "--right", default=None, help="Object on the right")
    creds.add_argument("-t", "--type", default=None, help="Object type")
    args = creds.get()

    # Arg validation
    if args.right is None:
        fatal("[E] Right object missing. Please pass it using --right <obj_name>")
    if args.left is None:
        fatal("[E] Left object missing. Please pass it using --left <obj_name>")
    if args.type is None:
        sys.stderr.write("[W] WARNING: No type supplied. Defaulting to 'Tenant'\n")
        args.type = "Tenant"

    # Process the supplied left and right data, according to the supplied type
Beispiel #14
0
def acilint():
    """
    Main execution routine

    :return: None
    """
    description = ('acilint - A static configuration analysis tool. '
                   'Checks can be individually disabled by generating'
                   ' and editing a configuration file.  If no config '
                   'file is given, all checks will be run.')
    creds = Credentials('apic', description)
    creds.add_argument('-c', '--configfile', type=argparse.FileType('r'))
    creds.add_argument('-g', '--generateconfigfile',
                       type=argparse.FileType('w'))
    creds.add_argument('-o', '--output', required=False, default='console')
    args = creds.get()
    if args.generateconfigfile:
        print('Generating configuration file....')
        f = args.generateconfigfile
        f.write(('# acilint configuration file\n# Remove or comment out any '
                 'warnings or errors that you no longer wish to see\n'))
        methods = dir(Checker)
        for method in methods:
            if method.startswith(('warning_', 'critical_', 'error_')):
                f.write(method + '\n')
        f.close()
        sys.exit(0)

    methods = []
    if args.configfile:
        f = args.configfile
        for line in f:
            method = line.split('\n')[0]
            if method in dir(Checker) and method.startswith(('warning_', 'error_', 'critical_')):
                methods.append(method)
        f.close()
    else:
        for method in dir(Checker):
            if method.startswith(('warning_', 'error_', 'critical_')):
                methods.append(method)

    if args.snapshotfiles:
        session = FakeSession(filenames=args.snapshotfiles)
    else:
        # Login to APIC
        session = Session(args.url, args.login, args.password)
        resp = session.login()
        if not resp.ok:
            print('%% Could not login to APIC')
            sys.exit(0)

    html = None
    if args.output == 'html':
        print('Creating file lint.html')
        html = open('lint.html', 'w')
        html.write("""
        <table border="2" style="width:100%">
        <tr>
        <th>Severity</th>
        <th>Rule</th>
        <th>Description</th>
        </tr>
        """)

    checker = Checker(session, args.output, html)
    checker.execute(methods)
    output("                                                                   ")
    output("  == A tool to deploy physical configuration on an ACI fabric ==   \n")

# Start of the execution
if __name__ == "__main__":
    
    # Argument parsing. We use the ACI toolkit logic here, which tries to
    # retrieve credentials from the following places:
    # 1. Command line options
    # 2. Configuration file called credentials.py
    # 3. Environment variables
    # 4. Interactively querying the user
    # At the end, we should have an object args with all the necessary info.
    description = 'APIC credentials'
    creds = Credentials('apic', description)
    creds.add_argument('-i', "--input", default=None, help='Input file')
    creds.add_argument('-d', "--debug", default=None, help='Input file')
    args = creds.get()
    
    # Let's check if the user passed all relevant parameters
    if args.input is None:
        fatal("[E] Input filename missing. Please pass it using --input <filename>")
    if args.debug is not None:
        debug_enable()

    # First of all, parse the input file.
    data = parse_spreadsheet(args.input)
    
    interfaces = [] # List of interfaces to push to the fabric
    
    for config_line in data['PortMapping']:        
Beispiel #16
0
def get_interface_stats_from_nodes():
    """
    Main execution routine

    :return: None
    """
    description = ('get_stats - A program to fetch statistics from an ACI '
                   'Fabric.')
    creds = Credentials('apic', description)
    creds.add_argument('-f',
                       '--format',
                       required=False,
                       default='text',
                       help='Specify output format [csv, text]')
    creds.add_argument('-i',
                       '--interval',
                       required=False,
                       default='15min',
                       help='Specify the aggregation interval')
    creds.add_argument('-n',
                       '--node_type',
                       required=False,
                       default='spine',
                       help='Specify the type of node [spine, leaf, both]')
    creds.add_argument('-t',
                       '--threshold',
                       required=False,
                       default=60,
                       type=int,
                       help='Specify the threshold for printing usage.')
    creds.add_argument('-v',
                       '--verbose',
                       action='count',
                       help='Specify verbosity of debug output.')

    args = creds.get()
    if args.format not in ['text', 'csv']:
        print >> sys.stderr, "Error: Unknown output format: '{}'".format(
            args.format)
        sys.exit(3)
    if args.interval not in [
            '5min', '15min', '1h', '1d', '1w', '1mo', '1qtr', '1year'
    ]:
        print >> sys.stderr, "Error: Unknown interval '{}'".format(
            args.interval)
        sys.exit(4)
    if args.node_type in ['spine', 'leaf']:
        node_type = [args.node_type]
    elif args.node_type in ['both']:
        node_type = ['spine', 'leaf']
    else:
        print >> sys.stderr, "Error: Unknown node type: '{}'".format(
            args.node_type)
        sys.exit(5)
    if args.threshold > 100:
        threshold = 100
    elif args.threshold < 0:
        threshold = 0
    else:
        threshold = args.threshold

    # Login to APIC
    session = Session(args.url, args.login, args.password)
    resp = session.login()
    if not resp.ok:
        print '%% Could not login to APIC'
        sys.exit(0)

    statistics = Stats(session, args.format, args.verbose)
    statistics.get_int_traffic(node_type, args.interval, threshold)
Beispiel #17
0
    def run():
        # Argument parsing. We use the ACI toolkit logic here, which tries to
        # retrieve credentials from the following places:
        # 1. Command line options
        # 2. Configuration file called credentials.py
        # 3. Environment variables
        # 4. Interactively querying the user
        # At the end, we should have an object args with all the necessary info.
        description = "APIC credentials"
        creds = Credentials("apic", description)
        creds.add_argument("-d", "--debug", default=None, help="Enable debug mode")
        creds.add_argument("-A", "--address", default=None, help="Local IP address")
        creds.add_argument("-P", "--port", default=None, help="Local Port for FTP connections")
        creds.add_argument("-K", "--key", default=None, help="ACI encryption key")
        args = creds.get()

        # Print welcome banner
        ACIExport.print_banner()

        # Let's check if the user passed all relevant parameters
        if args.debug is not None:
            debug_enable()
        if args.address is None:
            # If the user didn't pass any IP address, let's figure out what IPs we
            # have configured locally. If it's only one, use it. Otherwise, ask
            # the user interactively to pick one
            candidates = {}
            for iface in netifaces.interfaces():
                for addr in netifaces.ifaddresses(iface):
                    addr_str = netifaces.ifaddresses(iface)[addr][0]["addr"]
                    # Skip IPv6 addresses
                    if addr_str.count(":") > 0:
                        continue
                    # Skip localhost and unassigned addresses
                    elif addr_str == "0.0.0.0" or addr_str == "127.0.0.1":
                        continue
                    # Skip Microsoft auto-assigned addresses
                    elif addr_str.startswith("169.254."):
                        continue
                    else:
                        candidates[addr_str] = addr_str
            output("Please indicate which local IP address should be used (enter its sequence number):")
            for i in range(0, len(candidates)):
                print(" -> [%i] %s" % (i, candidates.keys()[i]))
            answer = -1
            while not (answer >= 0 and answer < len(candidates)):
                try:
                    answer = int(input("$: "))
                except:
                    continue
            args.address = candidates[candidates.keys()[answer]]
            output("Address selected: %s" % args.address)
        if args.port is None:
            args.port = DEFAULT_FTP_PORT
        else:
            args.port = int(args.port)
        if args.key is None:
            args.key = DEFAULT_KEY

        # Now, we log into the APIC
        fabric = Fabric(args.url, args.login, args.password)
        fabric.connect()

        # Instance our FTP server
        ftplistener = FTPListener(addr=args.address, port=args.port)
        ftplistener.daemon = True
        ftplistener.start()

        # Nasty thing: sleep for 1 sec to give enough time to the FTP server to
        # initialize @todo: use decent concurrency control mechanisms
        time.sleep(1)

        # Push config to the fabric
        pols = ConfExportPolicy(addr=args.address, port=args.port, key=args.key)
        fabric.push_to_apic(pols)

        output("Waiting for the ACI fabric to send its configuration export file...")
        while g_do_exit is False:
            time.sleep(1)

        output("File '%s' was successfully received. Closing..." % g_recv_file)

        output("Please make a note of the encryption key: '%s'" % args.key)

        # Finally, stop the server and quit
        ftplistener.stop()

        return True