Python – Assesing each line in a file against an IF

Question:

The below works for a single ip or fqdn, but for a list of assets its failing and assigning them all as FQDNs.

#!/usr/bin/env python

import argparse
import ipaddress
import re

def parse_args():
    # Assess arguments
    parser = argparse.ArgumentParser(description='do some sh*t')
    parser.add_argument('-T', required=True, choices=['single','filename'], help='Type of input i.e. single asset name or file of assets')
    parser.add_argument('-A', required=True, help='Asset name or file name')

    args = parser.parse_args()
    args = vars(args)
    asset_type = (args['T'])
    if asset_type == 'single':
        single_asset(args)
    elif asset_type == 'filename':
        filename_asset(args)
    else:
        raise Exception('Unexpected asset type')


def single_asset(args):
    # Function for single asset type
    print ('single_asset function')
    asset = (args['A'])
    identify_asset_type(asset)


def filename_asset(args):
    # Function for file of assets
    print ('filename_asset function')
    filename = (args['A'])
    with open(filename, 'r') as filename_input:
        for asset in filename_input:
            identify_asset_type(asset) 

def identify_asset_type(asset):
    # Identify if IP address, FQDN or other
    try:
        if ipaddress.ip_address(asset):
            print(f'IP address - {asset}')
    except ValueError:
        if re.match(r'^(?!.{255}|.{253}[^.])([a-z0-9](?:[-a-z-0-9]{0,61}[a-z0-9])?.)*[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?[.]?$', asset, re.IGNORECASE):
            print (f'FQDN - valid {asset}')
        else:
            print ('Not an IP or FQDN')

This is with a list of assets such as:

apple
123.4.5.1
bob.com
20.10.4.6
300.100.200.50

How do i structure this code please so that when parse_args is run with -T filename -A name_of_file it will assess each line properly? Especially as the last item in the test input is not a valid IP.

Thank you

Asked By: yeleek

||

Answers:

parse_args should limit itself to what’s in its name: parse the command line arguments. It return args, and the caller can decide which function to call to process the named file.

Once you have the args, build a list of assets. This will contain either the single asset specified by the -A option, or a list of assets read from the file named by the -A option.

Once you have the list of assets, iterate over it and call identify_asset_type on each.

#!/usr/bin/env python

import argparse
import ipaddress
import re

def parse_args():
    # Assess arguments
    parser = argparse.ArgumentParser(description='do some sh*t')
    parser.add_argument('-T', required=True, choices=['single','filename'], help='Type of input i.e. single asset name or file of assets')
    parser.add_argument('-A', required=True, help='Asset name or file name')

    return parser.parse_args()


DOMAIN_RE = r'^(?!.{255}|.{253}[^.])([a-z0-9](?:[-a-z-0-9]{0,61}[a-z0-9])?.)*[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?[.]?$'

def identify_asset_type(asset):
    try:
        # No if needed. The print statement executes if and only if
        # no ValueError is raised.
        ipaddress.ip_address(asset)
        print(f'IP address - {asset}')
    except ValueError:
        if re.match(DOMAIN_RE, asset, re.IGNORECASE):
            print (f'FQDN - valid {asset}')
        else:
            print ('Not an IP or FQDN')


if __name__ == '__main__':

    args = parse_args()

    asset_type = args.T   
    if asset_type == 'single':
        assets = [args.A]
    elif asset_type == 'filename':
        with open(args.A) as f:
            assets = [x.strip() for x in f]
    
    for asset in assets:
        identify_asset_type(asset)
Answered By: chepner
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.