Commit 1ce01ab2 authored by Bob Harold's avatar Bob Harold
Browse files

Merge branch 'master' into 'dev'

# Conflicts:
#   .gitlab-ci.yml
#   .pylintrc
#   src/bluecat_bam/api.py
parents 6f7cc45b 58298bd7
Pipeline #58810 passed with stages
in 1 minute and 3 seconds
[BASIC]
# pylint confuses constants with variables, so regex to cover both
const-rgx=^([a-z_][a-z0-9_]{2,30}|[A-Z_][A-Z0-9_]{2,30})$
const-rgx=^([a-z_][a-z0-9_]{0,30}|[A-Z_][A-Z0-9_]{0,30})$
variable-rgx=^[a-z_][a-zA-Z0-9_]{0,35}$
module-rgx=^[a-z_][a-zA-Z0-9_]{2,35}$
argument-rgx=^[a-z_][a-zA-Z0-9_]{2,35}$
include-naming-hint=y
# expect duplicate code, for stand-alone modules
# might refactor someday
disable=duplicate-code
disable=duplicate-code,C0330
# show error msg_id, so I can use it in 'disable' if needed, to save space
msg-template={msg_id}:{line:3d},{column}: {obj}: {msg}
# need more args in my BAM.__init__
max-args=8
max-args=10
max-locals=20
# to disable a line, add at end like
# fred_DNS=0 # pylint: disable=W0105
#!/usr/bin/env python
"""
add_DHCP_Deployment_Role_list.py primaryDHCPservername [failoverDHCPservername]
[--cfg configuration]
< list-of-IP-or-CIDR
"""
# to be python2/3 compatible:
from __future__ import print_function
import os
import sys
import json
import argparse
import logging
import bluecat_bam
__progname__ = "add_DHCP_Deployment_Role_list"
__version__ = "0.1"
def argparsecommon():
"""set up common argparse arguments for BlueCat API"""
config = argparse.ArgumentParser(
description="BlueCat Address Manager add_DNS_Deployment_Role_list"
)
config.add_argument(
"--server",
"-s",
# env_var="BLUECAT_SERVER",
default=os.getenv("BLUECAT_SERVER"),
help="BlueCat Address Manager hostname",
)
config.add_argument(
"--username",
"-u",
# env_var="BLUECAT_USERNAME",
default=os.getenv("BLUECAT_USERNAME"),
)
config.add_argument(
"--password",
"-p",
# env_var="BLUECAT_PASSWORD",
default=os.getenv("BLUECAT_PASSWORD"),
help="password in environment, should not be on command line",
)
config.add_argument(
"--configuration",
"--cfg",
help="BlueCat Configuration name",
default=os.getenv("BLUECAT_CONFIGURATION"),
)
config.add_argument(
"--raw",
"-r",
default=os.getenv("BLUECAT_RAW"),
help="set to true to not convert strings like 'name=value|...' "
+ "to dictionaries on output. Will accept either format on input.",
)
config.add_argument(
"--version", action="version", version=__progname__ + ".py " + __version__
)
config.add_argument(
"--logging",
"-l",
help="log level, default WARNING (30),"
+ "caution: level DEBUG(10) or less will show the password in the login call",
default=os.getenv("BLUECAT_LOGGING", "WARNING"),
)
return config
def getinterfaceid(server_name, configuration_id, conn):
"""get server interface id, given the server name"""
interface_obj_list = conn.do(
"searchByObjectTypes",
keyword=server_name,
types="NetworkServerInterface",
start=0,
count=2, # error if more than one
)
if len(interface_obj_list) > 1:
print("ERROR - more than one interface found", json.dumps(interface_obj_list))
sys.exit(3)
interfaceid = interface_obj_list[0]["id"]
if interfaceid != 0:
return interfaceid
# try another method, in case they gave the server display name instead
server_obj_list = conn.do(
"getEntitiesByName",
parentId=configuration_id,
name=server_name,
type="Server",
start=0,
count=2, # error if more than one
)
# print(json.dumps(server_obj_list))
if len(server_obj_list) > 1:
print(
"ERROR - found more than one server for name",
server_name,
json.dumps(server_obj_list),
)
sys.exit(1)
if len(server_obj_list) < 1:
print("ERROR - server not found for", server_name)
sys.exit(1)
server_id = server_obj_list[0]["id"]
if server_id == 0:
print("ERROR - server not found for name", server_name)
sys.exit(1)
interface_obj_list = conn.do(
"getEntities",
method="get",
parentId=server_id,
type="NetworkServerInterface",
start=0,
count=1000,
)
if len(interface_obj_list) > 1:
print("ERROR - more than one interface found", json.dumps(interface_obj_list))
sys.exit(3)
interfaceid = interface_obj_list[0]["id"]
if interfaceid == 0:
print("ERROR - interface not found")
sys.exit(4)
return interfaceid
def add_dhcp_roles(entityId, interfaceid, properties, conn):
"""found entityId that needs DHCP roles, now add them"""
role = conn.do(
"getDHCPDeploymentRole",
method="get",
entityId=entityId,
serverInterfaceId=interfaceid,
)
roleid = role["id"]
if roleid != 0:
print("role", roleid, "exists for network")
else:
roleid = conn.do(
"addDHCPDeploymentRole",
method="post",
entityId=entityId,
serverInterfaceId=interfaceid,
type="MASTER",
properties=properties,
)
return roleid
def get_network(network_ip, configuration_id, conn):
"""find network for an IP"""
# bam getIPRangedByIP containerId=21216763 type=IP4Block address=10.2.1.0
network_obj = conn.do(
"getIPRangedByIP",
method="get",
containerId=configuration_id,
type="IP4Network",
address=network_ip,
)
if network_obj["id"] == 0:
network_obj = {}
return network_obj
def main():
"""add DNS Deployment Role list"""
config = argparsecommon()
config.add_argument("primaryDHCPservername")
# cannot use None as a default value
config.add_argument("failoverDHCPservername", default="fred")
args = config.parse_args()
logger = logging.getLogger()
logging.basicConfig(format="%(asctime)s %(levelname)s: %(message)s")
logger.setLevel(args.logging)
configuration_name = args.configuration
with bluecat_bam.BAM(args.server, args.username, args.password) as conn:
configuration_obj = conn.do(
"getEntityByName",
method="get",
parentId=0,
name=configuration_name,
type="Configuration",
)
configuration_id = configuration_obj["id"]
interfaceid = getinterfaceid(args.primaryDHCPservername, configuration_id, conn)
if args.failoverDHCPservername:
failover = getinterfaceid(
args.failoverDHCPservername, configuration_id, conn
)
properties = "secondaryServerInterfaceId=" + str(failover) + "|"
else:
properties = ""
# now work through the zones
for cidr in sys.stdin:
# pattern match to cidr or zone name, fwd or rev
# set zone_name, and cidr if applicable
cidr = cidr.strip()
if "/" in cidr:
ip = cidr.split("/")[0]
# (ip, prefix) = cidr.split("/")
# print("CIDR", cidr, "ip", ip, "prefix", prefix)
else:
ip = cidr
# find the block or network
entity = get_network(ip, configuration_id, conn)
if not entity:
print("network not found", cidr)
continue
# print("found entity", json.dumps(entity))
# found entityId that needs DNS roles, now add them
entityId = entity["id"]
roleid = add_dhcp_roles(entityId, interfaceid, properties, conn)
print("Network", cidr, "DHCP-roleid", roleid)
if __name__ == "__main__":
main()
#!/usr/bin/env python
"""add_DHCP_Reserved.py [--server servername] -f <filename>
OR
add_DHCP_Reserved.py --ip IP --mac MAC --ipname DESC --hostname NAME
(other options available)
"""
# to be python2/3 compatible:
from __future__ import print_function
import os
import sys
import json
import argparse
import logging
import bluecat_bam
config = argparse.ArgumentParser(description="add DHCP Reserved")
config.add_argument(
"--server",
"-s",
# env_var="BLUECAT_SERVER",
default=os.getenv("BLUECAT_SERVER"),
help="BlueCat Address Manager hostname",
)
config.add_argument(
"--username",
"-u",
# env_var="BLUECAT_USERNAME",
default=os.getenv("BLUECAT_USERNAME"),
)
config.add_argument(
"--password",
"-p",
# env_var="BLUECAT_PASSWORD",
default=os.getenv("BLUECAT_PASSWORD"),
help="password in environment, should not be on command line",
)
config.add_argument(
"--configuration",
"--cfg",
help="BlueCat Configuration name",
default=os.getenv("BLUECAT_CONFIGURATION"),
)
config.add_argument("--view", help="BlueCat View", default=os.getenv("BLUECAT_VIEW"))
config.add_argument(
"--file",
"--filename",
"-f",
help="filename (--file OR --ip and --mac can be used, but not both)",
)
config.add_argument("--ip", "-i", "-a", "--address", help="ip address")
config.add_argument(
"--mac", "-m", "--hw", "--hardware", help="Interface MAC or HW address"
)
config.add_argument("--ipname", help="optional - name for the IP object")
config.add_argument(
"--host", "--hostname", "--fqdn", "--dns", "-d", help="optional - hostname"
)
config.add_argument(
"--logging",
"-l",
help="log level, default WARNING (30),"
+ "caution: level DEBUG(10) or less will show the password in the login call",
default=os.getenv("BLUECAT_LOGGING", "WARNING"),
)
args = config.parse_args()
logger = logging.getLogger()
logging.basicConfig(format="%(asctime)s %(levelname)s: %(message)s")
logger.setLevel(args.logging)
configuration_name = args.configuration
view_name = args.view
filename = args.file
ip = args.ip
mac = args.mac
ipname = args.ipname
hostname = args.host
if not (configuration_name and view_name):
print("--config and --view must be defined")
config.print_help()
sys.exit(1)
if filename:
if ip or mac:
print("--file cannot be used with --ip and --mac, use one or other")
config.print_help()
sys.exit(1)
elif not (ip and mac):
print("either --file OR both ( --ip and --mac ) must be specified")
config.print_help()
sys.exit(1)
with bluecat_bam.BAM(args.server, args.username, args.password) as conn:
configuration_obj = conn.do(
"getEntityByName",
method="get",
parentId=0,
name=configuration_name,
type="Configuration",
)
configuration_id = configuration_obj["id"]
view_obj = conn.do(
"getEntityByName",
method="get",
parentId=configuration_id,
name=view_name,
type="View",
)
view_id = view_obj["id"]
"""
network_obj = conn.do(
"getIPRangedByIP",
method="get",
containerId=configuration_id,
type="IP4Network",
address=ip,
)
network_id = network_obj["id"]
"""
if hostname:
hostinfo_list = [
hostname,
str(view_id),
"reverseFlag=true",
"sameAsZoneFlag=false",
]
hostinfo = ",".join(hostinfo_list)
else:
hostinfo = ""
new_ip_id = conn.do(
"assignIP4Address",
method="post",
configurationId=configuration_id,
ip4Address=ip,
macAddress=mac,
hostInfo=hostinfo,
action="MAKE_DHCP_RESERVED",
properties="",
)
# print(new_ip_id)
new_ip_obj = conn.do("getEntityById", id=new_ip_id)
# print(json.dumps(new_ip_obj))
newid = new_ip_obj["id"]
# cannot set object name in previous call, so update it with the name
# use hostname for the object name
if ipname:
new_ip_obj["name"] = ipname
updated_ip_obj = conn.do("update", method="put", data=new_ip_obj)
new_ip_obj = conn.do("getEntityById", method="get", id=newid)
print(json.dumps(new_ip_obj))
#!/usr/bin/env python
"""add_DNS_Deployment_Role.py entityId serverInterfaceId type properties"""
# to be python2/3 compatible:
from __future__ import print_function
import os
import argparse
import logging
import bluecat_bam
__progname__ = "add_DNS_Deployment_Role"
__version__ = "0.1"
def main():
"""add DNS Deploymetn Role"""
config = argparse.ArgumentParser(
description="BlueCat Address Manager add_DNS_Deployment_Role"
)
config.add_argument(
"--server",
"-s",
# env_var="BLUECAT_SERVER",
default=os.getenv("BLUECAT_SERVER"),
help="BlueCat Address Manager hostname",
)
config.add_argument(
"--username",
"-u",
# env_var="BLUECAT_USERNAME",
default=os.getenv("BLUECAT_USERNAME"),
)
config.add_argument(
"--password",
"-p",
# env_var="BLUECAT_PASSWORD",
default=os.getenv("BLUECAT_PASSWORD"),
help="password in environment, should not be on command line",
)
config.add_argument(
"--raw",
"-r",
default=os.getenv("BLUECAT_RAW"),
help="set to true to not convert strings like 'name=value|...' "
+ "to dictionaries on output. Will accept either format on input.",
)
config.add_argument(
"--version", action="version", version=__progname__ + ".py " + __version__
)
config.add_argument(
"--logging",
"-l",
help="log level, default WARNING (30),"
+ "caution: level DEBUG(10) or less will show the password in the login call",
default=os.getenv("BLUECAT_LOGGING", "WARNING"),
)
config.add_argument("entityId")
config.add_argument("serverInterfaceId")
config.add_argument("type")
config.add_argument("properties")
args = config.parse_args()
logger = logging.getLogger()
logging.basicConfig(format="%(asctime)s %(levelname)s: %(message)s")
logger.setLevel(args.logging)
entityId = args.entityId
serverInterfaceId = args.serverInterfaceId
obj_type = args.type
properties = args.properties
with bluecat_bam.BAM(args.server, args.username, args.password) as conn:
roleid = conn.do(
"addDNSDeploymentRole",
method="post",
entityId=entityId,
serverInterfaceId=serverInterfaceId,
type=obj_type,
properties=properties,
)
print(roleid)
if __name__ == "__main__":
main()
#!/usr/bin/env python
"""
add_DNS_Deployment_Role_list.py list-of-DNSservername-and-role
[--cfg configuration] [--view viewname]
< list-of-CIDR-or-zonename
"""
# to be python2/3 compatible:
from __future__ import print_function
import os
import sys
import json
import argparse
import logging
import re
import bluecat_bam
__progname__ = "add_DNS_Deployment_Role_list"
__version__ = "0.1"
def argparsecommon():
"""set up common argparse arguments for BlueCat API"""
config = argparse.ArgumentParser(
description="BlueCat Address Manager add_DNS_Deployment_Role_list"
)
config.add_argument(
"--server",
"-s",
# env_var="BLUECAT_SERVER",
default=os.getenv("BLUECAT_SERVER"),
help="BlueCat Address Manager hostname",
)
config.add_argument(
"--username",
"-u",
# env_var="BLUECAT_USERNAME",
default=os.getenv("BLUECAT_USERNAME"),
)
config.add_argument(
"--password",
"-p",
# env_var="BLUECAT_PASSWORD",
default=os.getenv("BLUECAT_PASSWORD"),
help="password in environment, should not be on command line",
)
config.add_argument(
"--configuration",
"--cfg",
help="BlueCat Configuration name",
default=os.getenv("BLUECAT_CONFIGURATION"),
)
config.add_argument(
"--view", help="BlueCat View", default=os.getenv("BLUECAT_VIEW")
)
config.add_argument(
"--raw",
"-r",
default=os.getenv("BLUECAT_RAW"),
help="set to true to not convert strings like 'name=value|...' "
+ "to dictionaries on output. Will accept either format on input.",
)
config.add_argument(
"--version", action="version", version=__progname__ + ".py " + __version__
)
config.add_argument(
"--logging",
"-l",
help="log level, default WARNING (30),"
+ "caution: level DEBUG(10) or less will show the password in the login call",
default=os.getenv("BLUECAT_LOGGING", "WARNING"),
)
return config
def readserverlist(serverlistfile, conn, configuration_id):
"""read server list file, create interfaces table"""
interface_list = []
role_validation = { # define a set
"NONE",
"MASTER",
"MASTER_HIDDEN",
"SLAVE",
"SLAVE_STEALTH",
"FORWARDER",
"STUB",
"RECURSION",
"AD_MASTER",
}
with open(serverlistfile, "r") as filehandle:
for line in filehandle:
(server_name, role) = line.split()