import dns.query
import dns.resolver
+
def get_argument_parser():
parser = argparse.ArgumentParser(
- prog='update_dns_entry.py',
- description='Generate fixed-address DHCP configuration based for hosts based on DNS entries'
- )
- parser.add_argument(
- '-s', '--server', default=None, required=True,
- help='Server for DNS updates'
- )
- parser.add_argument(
- '-u', '--user', default=None,
- help='The user to use with samba-tool'
- )
- parser.add_argument(
- '-z', '--zone', required=True,
- help='The zone in which to update the entry'
+ prog="update_dns_entry.py",
+ description="Generate fixed-address DHCP configuration based for hosts based on DNS entries",
)
parser.add_argument(
- '-n', '--name', required=True,
- help='DNS entry name'
+ "-s", "--server", default=None, required=True, help="Server for DNS updates"
)
parser.add_argument(
- '-v', '--value', required=True,
- help='DNS entry value'
+ "-u", "--user", default=None, help="The user to use with samba-tool"
)
parser.add_argument(
- '-t', '--type', default='A',
- help='Entry type'
+ "-z", "--zone", required=True, help="The zone in which to update the entry"
)
+ parser.add_argument("-n", "--name", required=True, help="DNS entry name")
+ parser.add_argument("-v", "--value", required=True, help="DNS entry value")
+ parser.add_argument("-t", "--type", default="A", help="Entry type")
return parser
-def update_dns_entry(server, zone, name, entry_type, value, user=None, with_reverse = True):
+def update_dns_entry(
+ server, zone, name, entry_type, value, user=None, with_reverse=True
+):
if entry_type == "A":
- assert(ipaddress.ip_address(value))
+ assert ipaddress.ip_address(value)
try:
server_ip = str(ipaddress.ip_address(server))
except ValueError:
commands = []
# Verify existing entry
- query = dns.message.make_query('.'.join([name, zone]), entry_type)
- record = dns.query.udp(query, server_ip);
+ query = dns.message.make_query(".".join([name, zone]), entry_type)
+ record = dns.query.udp(query, server_ip)
if len(record.answer) == 0:
# Create
- argv = ['samba-tool', 'dns', 'add', server, zone, name, entry_type, value]
+ argv = ["samba-tool", "dns", "add", server, zone, name, entry_type, value]
if user is not None:
- argv += ['-U', user]
+ argv += ["-U", user]
commands.append(argv)
else:
- assert(len(record.answer) == 1)
+ assert len(record.answer) == 1
# Check validity
existing = (record.answer)[0][0].to_text()
if existing != value:
# Update
- argv = ['samba-tool', 'dns', 'update', server, zone, name, entry_type, existing, value]
+ argv = [
+ "samba-tool",
+ "dns",
+ "update",
+ server,
+ zone,
+ name,
+ entry_type,
+ existing,
+ value,
+ ]
if user is not None:
- argv += ['-U', user]
+ argv += ["-U", user]
commands.append(argv)
# Check reverse
- if with_reverse and entry_type == 'A':
- rname, rzone = ipaddress.ip_address(value).reverse_pointer.split('.', 1)
- rvalue = '.'.join([name, zone]) + '.'
- rtype = 'PTR'
- query = dns.message.make_query(ipaddress.ip_address(value).reverse_pointer, rtype)
+ if with_reverse and entry_type == "A":
+ rname, rzone = ipaddress.ip_address(value).reverse_pointer.split(".", 1)
+ rvalue = ".".join([name, zone]) + "."
+ rtype = "PTR"
+ query = dns.message.make_query(
+ ipaddress.ip_address(value).reverse_pointer, rtype
+ )
record = dns.query.udp(query, server_ip)
if len(record.answer) == 0:
- argv = ['samba-tool', 'dns', 'add', server, rzone, rname, rtype, rvalue]
+ argv = ["samba-tool", "dns", "add", server, rzone, rname, rtype, rvalue]
if user is not None:
- argv += ['-U', user]
+ argv += ["-U", user]
commands.append(argv)
else:
- assert(len(record.answer) == 1)
+ assert len(record.answer) == 1
existing = (record.answer)[0][0].to_text()
if existing != value:
- argv = ['samba-tool', 'dns', 'update', server, rzone, rname, rtype, existing, rvalue]
+ argv = [
+ "samba-tool",
+ "dns",
+ "update",
+ server,
+ rzone,
+ rname,
+ rtype,
+ existing,
+ rvalue,
+ ]
if user is not None:
- argv += ['-U', user]
+ argv += ["-U", user]
commands.append(argv)
# Run commands
subprocess.run(command, check=True)
-if __name__ == '__main__':
+if __name__ == "__main__":
parser = get_argument_parser()
args = parser.parse_args()
- update_dns_entry(args.server, args.zone, args.name, args.type, args.value, user=args.user)
+ update_dns_entry(
+ args.server, args.zone, args.name, args.type, args.value, user=args.user
+ )
import jenkins
+
def get_argument_parser():
parser = argparse.ArgumentParser(
- prog='update_jenkins_node.py',
- description='Create, update, or delete Jenkins nodes'
- )
- parser.add_argument(
- '-u', '--url', default=None,
- help='Jenkins server URL including protocol'
- )
- parser.add_argument(
- '--user', default=None,
- help='Jenkins username'
+ prog="update_jenkins_node.py",
+ description="Create, update, or delete Jenkins nodes",
)
parser.add_argument(
- '--password', default=None,
- help='Jenkins password'
+ "-u", "--url", default=None, help="Jenkins server URL including protocol"
)
+ parser.add_argument("--user", default=None, help="Jenkins username")
+ parser.add_argument("--password", default=None, help="Jenkins password")
parser.add_argument(
- '-n', '--node', default=None, required=True,
- help='The name of the node to manage in Jenkins'
+ "-n",
+ "--node",
+ default=None,
+ required=True,
+ help="The name of the node to manage in Jenkins",
)
parser.add_argument(
- '-c', '--node-config', default=[], action='append',
- help='An equals-separated set path=value[=attrib]. When attrib is not set, text is assumed'
+ "-c",
+ "--node-config",
+ default=[],
+ action="append",
+ help="An equals-separated set path=value[=attrib]. When attrib is not set, text is assumed",
)
parser.add_argument(
- '-f', '--config-file', default=None, type=argparse.FileType('r'),
- help='An INI config file as used by jenkins_jobs'
+ "-f",
+ "--config-file",
+ default=None,
+ type=argparse.FileType("r"),
+ help="An INI config file as used by jenkins_jobs",
)
parser.add_argument(
- '-s', '--state', default='online',
- choices=['online', 'offline', 'absent'],
- help='The state of the Jenkins node'
+ "-s",
+ "--state",
+ default="online",
+ choices=["online", "offline", "absent"],
+ help="The state of the Jenkins node",
)
parser.add_argument(
- '-m', '--message', default='',
- help='A message to set for the offline reason of a node'
+ "-m",
+ "--message",
+ default="",
+ help="A message to set for the offline reason of a node",
)
parser.add_argument(
- '-j', '--json', default='',
- help='Additional config in a json dictionary which will be appended after -c items',
+ "-j",
+ "--json",
+ default="",
+ help="Additional config in a json dictionary which will be appended after -c items",
)
return parser
-def manage_node(url, user, password, node, state, offline_message='', config={}):
+def manage_node(url, user, password, node, state, offline_message="", config={}):
server = jenkins.Jenkins(url, username=user, password=password)
exists = server.node_exists(node)
node_info = {}
changed = False
- if exists and state == 'absent':
+ if exists and state == "absent":
server.delete_node(node)
changed = True
- if not exists and state != 'absent':
- server.create_node(node, numExecutors=1, remoteFS='/home/jenkins',
- launcher=jenkins.LAUNCHER_SSH)
+ if not exists and state != "absent":
+ server.create_node(
+ node,
+ numExecutors=1,
+ remoteFS="/home/jenkins",
+ launcher=jenkins.LAUNCHER_SSH,
+ )
changed = True
- if state != 'absent':
+ if state != "absent":
# Check configuration
updated = False
node_config = xml.etree.ElementTree.fromstring(server.get_node_config(node))
new_element = None
current_key = key
while element is None:
- head = key.rsplit('/', 1)[0] if '/' in current_key else None
- tail = key.rsplit('/', 1)[1] if '/' in current_key else current_key
+ head = key.rsplit("/", 1)[0] if "/" in current_key else None
+ tail = key.rsplit("/", 1)[1] if "/" in current_key else current_key
e = xml.etree.ElementTree.Element(tail)
if new_element is not None:
e.append(new_element)
current_key = head
continue
- if value['attrib'] is None:
- if element.text != value['value']:
+ if value["attrib"] is None:
+ if element.text != value["value"]:
updated = True
- element.text = value['value']
+ element.text = value["value"]
else:
try:
- if element.attrib[value['attrib']] != value['value']:
+ if element.attrib[value["attrib"]] != value["value"]:
updated = True
- element.attrib[value['attrib']] = value['value']
+ element.attrib[value["attrib"]] = value["value"]
except KeyError:
- element.attrib[value['attrib']] = value['value']
+ element.attrib[value["attrib"]] = value["value"]
updated = True
if updated:
xml_string = xml.etree.ElementTree.tostring(
- node_config,
- xml_declaration=True,
- encoding='unicode'
+ node_config, xml_declaration=True, encoding="unicode"
)
server.reconfig_node(node, xml_string)
changed = True
# Online/offline
node_info = server.get_node_info(node)
- if node_info['offline'] and state == 'online':
+ if node_info["offline"] and state == "online":
server.enable_node(node)
changed = True
- if not node_info['offline'] and state == 'offline':
+ if not node_info["offline"] and state == "offline":
server.disable_node(node, offline_message)
changed = True
return changed
-if __name__ == '__main__':
+if __name__ == "__main__":
parser = get_argument_parser()
args = parser.parse_args()
if args.config_file is not None:
config = configparser.ConfigParser()
config.read_file(args.config_file)
- if 'jenkins' not in config.sections():
+ if "jenkins" not in config.sections():
print("[jenkins] section not found")
sys.exit(1)
if args.url is None:
- args.url = config.get('jenkins', 'url')
+ args.url = config.get("jenkins", "url")
if args.user is None:
- args.user = config['jenkins']['user']
+ args.user = config["jenkins"]["user"]
if args.password is None:
- args.password = config['jenkins']['password']
- assert(args.user is not None)
- assert(args.url is not None)
- assert(args.password is not None)
+ args.password = config["jenkins"]["password"]
+ assert args.user is not None
+ assert args.url is not None
+ assert args.password is not None
node_config = {}
for entry in args.node_config:
- key, value = entry.split('=', 1)
+ key, value = entry.split("=", 1)
node_config[key] = {
- 'attrib': value.split('=', 1)[1] if '=' in value else None,
- 'value': value.split('=', 1)[0] if '=' in value else value,
+ "attrib": value.split("=", 1)[1] if "=" in value else None,
+ "value": value.split("=", 1)[0] if "=" in value else value,
}
if args.json:
for key, value in json.loads(args.json).items():
node_config[key] = {
- 'attrib': value.split('=', 1)[1] if '=' in value else None,
- 'value': value.split('=', 1)[0] if '=' in value else value,
+ "attrib": value.split("=", 1)[1] if "=" in value else None,
+ "value": value.split("=", 1)[0] if "=" in value else value,
}
manage_node(
- args.url, args.user, args.password, args.node, args.state,
- args.message, node_config
+ args.url,
+ args.user,
+ args.password,
+ args.node,
+ args.state,
+ args.message,
+ node_config,
)