nxos_add_delete_vlan.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #!/usr/bin/env python2
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Copyright (c) 2017-2018 Joe Clarke <jclarke@cisco.com>
  5. # All rights reserved.
  6. #
  7. # Redistribution and use in source and binary forms, with or without
  8. # modification, are permitted provided that the following conditions
  9. # are met:
  10. # 1. Redistributions of source code must retain the above copyright
  11. # notice, this list of conditions and the following disclaimer.
  12. # 2. Redistributions in binary form must reproduce the above copyright
  13. # notice, this list of conditions and the following disclaimer in the
  14. # documentation and/or other materials provided with the distribution.
  15. #
  16. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. # SUCH DAMAGE.
  27. import time
  28. import os
  29. import pprint
  30. import argparse
  31. import sys
  32. import re
  33. from NXOSVlans import NXOSVlans
  34. if __name__ == '__main__':
  35. nav = NXOSVlans()
  36. parser = argparse.ArgumentParser(
  37. prog=sys.argv[0], description='Add or delete a VLAN to an NX-OS switch')
  38. parser.add_argument('--device', '-d', dest='device', metavar='<HOSTNAME|IP>',
  39. help='NX-OS device to which to add VLAN', required=True)
  40. parser.add_argument('--vlan', '-v', dest='vid',
  41. metavar='<VLAN_ID>', help='VLAN ID', type=int, required=True)
  42. parser.add_argument('--name', '-n', dest='vname',
  43. metavar='<VLAN_NAME>', help='VLAN Name')
  44. parser.add_argument('--username', '-u', dest='username',
  45. metavar='<USERNAME>', help='Device username', required=True)
  46. parser.add_argument('--trunks', '-t', dest='trunks', metavar='<TRUNK_PORT1 TRUNK_PORT2 ...>',
  47. nargs='+', help='List of trunk ports to which VLAN will be added')
  48. parser.add_argument('--svi', '-i', dest='svi',
  49. action='store_true', help='Create an SVI for this VLAN?')
  50. parser.add_argument('--description', '-e', dest='description',
  51. metavar='<DESCRIPTION>', help='SVI description')
  52. parser.add_argument('--ip', '-4', dest='ipv4', metavar='<IP_ADDRESS/CIDR>',
  53. help='SVI IPv4 address and subnet bits')
  54. parser.add_argument('--ip6', '-6', dest='ipv6', metavar='<IPV6_ADDRESS/LENGTH>',
  55. help='SVI IPv6 address and prefix length')
  56. parser.add_argument('--hsrp', '-r', dest='hsrpv4',
  57. metavar='<HSRP_IPV4_ADDRESS>', help='SVI HSRP virtual IPv4 address')
  58. parser.add_argument('--hsrpv6', '-R', dest='hsrpv6',
  59. metavar='<HSRP_IPV6_ADDRESS>', help='SVI HSRP virtual IPv6 address')
  60. parser.add_argument('--priority', '-p', dest='hsrp_priority',
  61. metavar='<PRIORITY>', type=int, help='SVI HSRP priority')
  62. parser.add_argument('--delete', '-D', action='store_true',
  63. dest='delete', help='Delete the specified VLAN')
  64. parser.set_defaults(svi=False, delete=False)
  65. parser.parse_args(namespace=nav)
  66. if not nav.delete and not nav.vname:
  67. parser.error('VLAN name must be specified')
  68. if not nav.delete and nav.svi and not nav.ipv4:
  69. parser.error('IPv4 address must be specified for the SVI')
  70. if not nav.delete and nav.svi and not nav.description:
  71. nav.description = '-> {}'.format(nav.name)
  72. if not nav.delete and nav.svi and nav.hsrpv6 and not nav.ipv6:
  73. parser.error('IPv6 address must be specified if HSRPv6 is used')
  74. if not nav.delete and not nav.svi and (nav.ipv4 or nav.ipv6 or nav.hsrpv4 or nav.hsrpv6):
  75. parser.error(
  76. 'IP and HSRP addresses can only be specified if --svi is given')
  77. if not nav.delete and nav.ipv4 and not re.match(r'[\d\.]+/\d+', nav.ipv4):
  78. parser.error(
  79. 'Invalid IPv4 address; must be in the format of ADDRESS/CIDR')
  80. if not nav.delete and nav.ipv6 and not re.match(r'[a-fA-F0-9:]+/\d+', nav.ipv6):
  81. parser.error(
  82. 'Invalid IPv6 address; must be in the format of ADDRESS/LENGTH')
  83. if not nav.delete and nav.hsrpv4 and not re.match(r'[\d\.]+', nav.hsrpv4):
  84. parser.error('Invalid HSRPv4 address')
  85. if not nav.delete and nav.hsrpv6 and not re.match(r'[a-fA-F0-9:]+', nav.hsrpv6):
  86. parser.error('Invalid HSRPv6 address')
  87. if not nav.delete and (nav.hsrpv4 or nav.hsrpv6) and not nav.hsrp_priority:
  88. parser.error('SVI HSRP priority must be specified')
  89. if 'NXOS_ADMIN_PW' not in os.environ:
  90. print('The environment variable "NXOS_ADMIN_PW" must be set with the password for {}'.format(
  91. nav.username))
  92. sys.exit(1)
  93. if nav.delete:
  94. res = nav.delete_l2_vlan()
  95. if not res:
  96. print('Error deleting VLAN {} from {}'.format(nav.vid, nav.device))
  97. sys.exit(1)
  98. else:
  99. res = nav.deploy_l2_vlan()
  100. if not res:
  101. print('Error deploying VLAN {} to {}; removing VLAN'.format(
  102. nav.vid, nav.device))
  103. nav.delete_l2_vlan()
  104. sys.exit(1)
  105. if nav.svi:
  106. res = nav.deploy_svi()
  107. if res:
  108. nav.write_config()
  109. else:
  110. print('Error deploying SVI for VLAN {} to {}; removing L2 VLAN'.format(
  111. nav.vid, nav.device))
  112. nav.delete_l2_vlan()
  113. sys.exit(1)