extend_scope.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/env python2
  2. #
  3. # Copyright (c) 2017-2019 Joe Clarke <jclarke@cisco.com>
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. # 1. Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. #
  15. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. # SUCH DAMAGE.
  26. import json
  27. import requests
  28. from requests.packages.urllib3.exceptions import InsecureRequestWarning
  29. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  30. import sys
  31. import CLEUCreds
  32. DHCP_BASE = 'https://dc1-dhcp.ciscolive.network:8443/web-services/rest/resource/Scope'
  33. IDF_CNT = 98
  34. HEADERS = {
  35. 'authorization': CLEUCreds.JCLARKE_BASIC,
  36. 'accept': 'application/json',
  37. 'content-type': 'application/json'
  38. }
  39. if __name__ == '__main__':
  40. if len(sys.argv) != 4:
  41. sys.stderr.write(
  42. "usage: {} VLAN <IDF|CORE> START\n".format(sys.argv[0]))
  43. sys.exit(1)
  44. vlan = sys.argv[1]
  45. type = sys.argv[2].upper()
  46. start = sys.argv[3]
  47. if type != 'CORE' and type != 'IDF':
  48. sys.stderr.write("usage: {} VLAN <IDF|CORE> START\n".format(sys.argv[0]))
  49. sys.exit(1)
  50. istart = 1
  51. prefix = 'IDF-' + str(istart).zfill(3)
  52. rs = 1
  53. cnt = IDF_CNT
  54. if type == 'CORE':
  55. prefix = 'CORE-'
  56. rs = 0
  57. cnt = 0
  58. first_scope_name = '{}-{}'.format(prefix, vlan.upper())
  59. url = '{}/{}'.format(DHCP_BASE, first_scope_name)
  60. try:
  61. response = requests.request('GET', url, headers=HEADERS, verify=False)
  62. response.raise_for_status()
  63. except Exception as e:
  64. sys.stderr.write(
  65. 'Failed to get first scope details for {}: {}\n'.format(first_scope_name, e))
  66. sys.exit(1)
  67. first_scope = response.json()
  68. end = first_scope['rangeList']['RangeItem'][0]['end'].split('.')[3]
  69. subnet = '.'.join(first_scope['subnet'].split('.')[0:2])
  70. policy = first_scope['policy']
  71. embedded_policy = None
  72. if 'embeddedPolicy' in first_scope:
  73. embedded_policy = first_scope['embeddedPolicy']
  74. for i in range(rs, cnt + 1):
  75. rstart = '{}.{}.{}'.format(subnet, i, start)
  76. eoctet = i
  77. if type == 'CORE':
  78. eoctet = 255
  79. rend = '{}.{}.{}'.format(subnet, eoctet, end)
  80. prefix = 'IDF-' + str(i).zfill(3)
  81. if embedded_policy is not None:
  82. embedded_policy = {
  83. 'optionList': {
  84. 'OptionItem': [
  85. {
  86. 'number': '3',
  87. 'value': '{}.{}.{}'.format(subnet, eoctet, str(254))
  88. }
  89. ]
  90. }
  91. }
  92. if type == 'CORE':
  93. prefix = 'CORE-'
  94. scope_name = '{}-{}'.format(prefix, vlan.upper())
  95. url = '{}/{}'.format(DHCP_BASE, scope_name)
  96. try:
  97. # print('Changing {} to start: {}, end: {}'.format(
  98. # scope_name, start, end))
  99. payload = {
  100. 'rangeList': {'RangeItem': [
  101. {'start': rstart, 'end': rend}]},
  102. 'policy': policy
  103. }
  104. if embedded_policy is not None:
  105. payload['embeddedPolicy'] = embedded_policy
  106. response = requests.request(
  107. 'PUT', url, json=payload, headers=HEADERS, verify=False)
  108. response.raise_for_status()
  109. except Exception as e:
  110. sys.stderr.write(
  111. 'Failed to update scope details for {}: {}\n'.format(scope_name, e))
  112. continue