November 21, 2024

The two previous posts described what the script does and modules used as well as how the script leverages YAML.

This time, we will go through the function that generates the access-list name. The code for this is below:

def generate_acl_name(interface_name: str) -> str: """Generate unique ACL name to avoid conflicts with any existing ACLs by appending a random number to the outside interface name""" # Create a random number between 1 and 999 random_number = random.randint(1, 999) acl_name = f"{interface_name}_{random_number}" return acl_name

The goal with this code is to generate a new access-list with a unique name. Note that the script doesn’t do any check if this access-list already exists which is something I will look into in an improved version of the script. I wanted to first start with something that works and take you through the process together with myself as I learn and improve on the existing code.

The function takes an interface_name which is a string. This is provided by the YAML data that we stored in the yaml_dict earlier. The function is then called like this:

acl_name = generate_acl_name(yaml_dict["outside_interface"])

The name is stored in the yaml_dict under the outside_interface mapping:

In [6]: yaml_dict = get_yaml_data() In [7]: yaml_dict
Out[7]: {'outside_interface': 'outside', 'aws_service': 's3', 'aws_region': 'eu-north-1', 'asa_ip': '192.168.255.241'} In [8]: yaml_dict["outside_interface"]
Out[8]: 'outside'

The value of outside_interface is outside, which is a string.

We then call the function generate_acl_name and input yaml_dict[“outside_interface”] as the value:

In [9]: acl_name = generate_acl_name(yaml_dict["outside_interface"]) In [10]: acl_name
Out[10]: 'outside_785'

The function returned the string outside_785. Now let’s go through the function in more detail:

def generate_acl_name(interface_name: str) -> str: """Generate unique ACL name to avoid conflicts with any existing ACLs by appending a random number to the outside interface name""" # Create a random number between 1 and 999 random_number = random.randint(1, 999) acl_name = f"{interface_name}_{random_number}" return acl_name

Line 1 defines the function and takes a string and stores it in interface_name and the function will also return a string.

Lines 2-3 is simply the docstring.

Line 4 is a comment.

Line 5 is where we generate a random number between 1 and 999 using the random.randint method. This is an integer stored in random_number variable.

Line 6 is where we use an f-string to combine the variable interface_name plus an underscore with the random_number. Keep in mind that interface_name is a string and random_number is an integer. This is not a problem with f-strings as it does type casting for us. If we were using a regular string, this would cause an error as you can’t normally form a string out of a string and an integer. This is shown below:

In [12]: random_number = 785 In [13]: outside_interface = "outside" In [14]: acl_name = outside_interface + "_" + random_number
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-d00d062f9c5e> in <module>
----> 1 acl_name = outside_interface + "_" + random_number TypeError: can only concatenate str (not "int") to str

Line 7 is then simply where we return the string that we created in line 6 named acl_name.

That’s all for this time! Hope you join me in the next post of this series.

Source