|
@@ -29,18 +29,15 @@ import sys
|
|
|
import json
|
|
|
from sparker import Sparker, MessageType # type: ignore
|
|
|
import re
|
|
|
-import requests
|
|
|
-from requests.packages.urllib3.exceptions import InsecureRequestWarning # type: ignore
|
|
|
-
|
|
|
-requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
|
|
import traceback
|
|
|
import logging
|
|
|
+from elemental_utils import ElementalDns
|
|
|
+from elemental_utils import cpnr
|
|
|
+from elemental_utils.cpnr.query import RequestError
|
|
|
+import os
|
|
|
import CLEUCreds # type: ignore
|
|
|
from cleu.config import Config as C # type: ignore
|
|
|
|
|
|
-CNR_HEADERS = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
|
-CNR_AUTH = (CLEUCreds.CPNR_USERNAME, CLEUCreds.CPNR_PASSWORD)
|
|
|
-
|
|
|
ALLOWED_TO_CREATE = [
|
|
|
"jclarke@cisco.com",
|
|
|
"anjesani@cisco.com",
|
|
@@ -56,110 +53,82 @@ spark = Sparker(token=CLEUCreds.SPARK_TOKEN, logit=True)
|
|
|
SPARK_ROOM = "DNS Queries"
|
|
|
|
|
|
|
|
|
-def check_for_alias(alias):
|
|
|
- global CNR_HEADERS, CNR_AUTH
|
|
|
-
|
|
|
- url = C.DNS_BASE + "/CCMRRSet" + "/{}".format(alias)
|
|
|
-
|
|
|
- response = requests.request("GET", url, params={"zoneOrigin": C.DNS_DOMAIN}, auth=CNR_AUTH, headers=CNR_HEADERS, verify=False)
|
|
|
- if response.status_code == 404:
|
|
|
- return None
|
|
|
-
|
|
|
- res = {}
|
|
|
- j = response.json()
|
|
|
-
|
|
|
- hostname = ""
|
|
|
-
|
|
|
- for rr in j["rrs"]["stringItem"]:
|
|
|
- m = re.search(r"^IN CNAME (.+)", rr)
|
|
|
- if m:
|
|
|
- hostname = m.group(1)
|
|
|
- break
|
|
|
-
|
|
|
- res["hostname"] = hostname
|
|
|
-
|
|
|
- return res
|
|
|
-
|
|
|
-
|
|
|
-def create_alias(hostname, alias):
|
|
|
- global CNR_HEADERS, CNR_AUTH
|
|
|
-
|
|
|
- url = C.DNS_BASE + "/CCMRRSet" + "/{}".format(alias)
|
|
|
-
|
|
|
- if re.search(r"\.", hostname) and not hostname.endswith("."):
|
|
|
- hostname += "."
|
|
|
-
|
|
|
- if not hostname.endswith("."):
|
|
|
- hostname += "." + C.DNS_DOMAIN + "."
|
|
|
-
|
|
|
- rr_obj = {"name": alias, "zoneOrigin": C.DNS_DOMAIN, "rrs": {"stringItem": ["IN CNAME {}".format(hostname)]}}
|
|
|
-
|
|
|
- response = requests.request("PUT", url, headers=CNR_HEADERS, auth=CNR_AUTH, json=rr_obj, verify=False)
|
|
|
- response.raise_for_status()
|
|
|
+def check_for_alias(edns: ElementalDns, alias: str) -> cpnr.models.model.Record:
|
|
|
+ rrset = edns.rrset.get(alias, zoneOrigin=C.DNS_DOMAIN + ".")
|
|
|
+ if rrset:
|
|
|
+ for rr in rrset.rrList["CCMRRItem"]:
|
|
|
+ if rr["rrType"] == "CNAME":
|
|
|
+ return rrset
|
|
|
|
|
|
+ return None
|
|
|
|
|
|
-def delete_alias(alias):
|
|
|
- global CNR_HEADERS, CNR_AUTH
|
|
|
|
|
|
- url = C.DNS_BASE + "/CCMRRSet" + "/{}".format(alias)
|
|
|
+def create_alias(edns: ElementalDns, hostname: str, alias: str):
|
|
|
+ cpnr_record = {}
|
|
|
|
|
|
- response = requests.request("DELETE", url, params={"zoneOrigin": C.DNS_DOMAIN}, auth=CNR_AUTH, headers=CNR_HEADERS, verify=False)
|
|
|
- response.raise_for_status()
|
|
|
+ cpnr_record["name"] = alias
|
|
|
+ cpnr_record["zoneOrigin"] = C.DNS_DOMAIN + "."
|
|
|
+ target = f"{hostname}.{C.DNS_DOMAIN}."
|
|
|
+ cpnr_record["rrList"] = {"CCMRRItem": [{"rdata": target, "rrClass": "IN", "rrType": "CNAME"}]}
|
|
|
|
|
|
+ edns.rrset.add(**cpnr_record)
|
|
|
|
|
|
-def delete_record(hostname):
|
|
|
- global CNR_HEADERS
|
|
|
|
|
|
- url = C.DNS_BASE + "/CCMHost" + "/{}".format(hostname)
|
|
|
- rrurl = C.DNS_BASE + "/CCMRRSet" + "/{}".format(hostname)
|
|
|
+def delete_alias(alias: cpnr.models.model.Record) -> None:
|
|
|
+ alias.delete()
|
|
|
|
|
|
- response = requests.request("DELETE", url, params={"zoneOrigin": C.DNS_DOMAIN}, headers=CNR_HEADERS, verify=False)
|
|
|
- response.raise_for_status()
|
|
|
-
|
|
|
- response = requests.request("DELETE", rrurl, params={"zoneOrigin": C.DNS_DOMAIN}, headers=CNR_HEADERS, verify=False)
|
|
|
-
|
|
|
-
|
|
|
-def check_for_record(hostname):
|
|
|
- global CNR_HEADERS, CNR_AUTH
|
|
|
-
|
|
|
- url = C.DNS_BASE + "/CCMHost" + "/{}".format(hostname)
|
|
|
-
|
|
|
- response = requests.request("GET", url, params={"zoneOrigin": C.DNS_DOMAIN}, auth=CNR_AUTH, headers=CNR_HEADERS, verify=False)
|
|
|
- if response.status_code == 404:
|
|
|
- return None
|
|
|
-
|
|
|
- res = {}
|
|
|
- j = response.json()
|
|
|
-
|
|
|
- res["ip"] = j["addrs"]["stringItem"][0]
|
|
|
-
|
|
|
- return res
|
|
|
-
|
|
|
-
|
|
|
-def create_record(hostname, ip, aliases, message_from):
|
|
|
- global CNR_HEADERS, CNR_AUTH
|
|
|
-
|
|
|
- url = C.DNS_BASE + "/CCMHost" + "/{}".format(hostname)
|
|
|
- host_obj = {"addrs": {"stringItem": [ip]}, "name": hostname, "zoneOrigin": C.DNS_DOMAIN}
|
|
|
|
|
|
+def delete_record(edns: ElementalDns, record: cpnr.models.model.Record) -> None:
|
|
|
+ name = record.name
|
|
|
+ rrset = edns.rrset.get(name, zoneOrigin=C.DNS_DOMAIN + ".")
|
|
|
+ try:
|
|
|
+ record.delete()
|
|
|
+ except RequestError as e:
|
|
|
+ if e.req.status_code != 404:
|
|
|
+ # We may end up deleting the same record twice.
|
|
|
+ # If it's already gone, don't complain.
|
|
|
+ raise
|
|
|
+
|
|
|
+ if rrset:
|
|
|
+ try:
|
|
|
+ rrset.delete()
|
|
|
+ except RequestError as e:
|
|
|
+ if e.req.status_code != 404:
|
|
|
+ # We may end up deleting the same record twice.
|
|
|
+ # If it's already gone, don't complain.
|
|
|
+ raise
|
|
|
+
|
|
|
+
|
|
|
+def check_for_record(edns: ElementalDns, hostname: str) -> cpnr.models.model.Record:
|
|
|
+ return edns.host.get(hostname, zoneOrigin=C.DNS_DOMAIN + ".")
|
|
|
+
|
|
|
+
|
|
|
+def create_record(edns: ElementalDns, hostname: str, ip: str, aliases: list, message_from: str) -> None:
|
|
|
+ cpnr_record = {}
|
|
|
+
|
|
|
+ cpnr_record["name"] = hostname
|
|
|
+ cpnr_record["addrs"] = {"stringItem": [ip]}
|
|
|
+ cpnr_record["zoneOrigin"] = C.DNS_DOMAIN + "."
|
|
|
+ cpnr_record["createPtrRecords"] = True
|
|
|
if aliases is not None:
|
|
|
aliases = re.sub(r"\s+", "", aliases)
|
|
|
alist = aliases.split(",")
|
|
|
|
|
|
alist = [x + "." + C.DNS_DOMAIN + "." if not x.endswith(".") else x for x in alist]
|
|
|
- host_obj["aliases"] = {"stringItem": alist}
|
|
|
+ cpnr_record["aliases"] = {"stringItem": alist}
|
|
|
|
|
|
- response = requests.request("PUT", url, headers=CNR_HEADERS, auth=CNR_AUTH, json=host_obj, verify=False)
|
|
|
- response.raise_for_status()
|
|
|
+ txt_record = f'IN TXT "v=_static created by: {message_from}'
|
|
|
|
|
|
- rr_obj = {"name": hostname, "zoneOrigin": C.DNS_DOMAIN, "rrs": {"stringItem": [f'IN TXT "v=_static created by: {message_from}']}}
|
|
|
- rrurl = C.DNS_BASE + "/CCMRRSet" + "/{}".format(hostname)
|
|
|
-
|
|
|
- response = requests.request("PUT", rrurl, headers=CNR_HEADERS, auth=CNR_AUTH, json=rr_obj, verify=False)
|
|
|
- response.raise_for_status()
|
|
|
+ edns.host.add(**cpnr_record)
|
|
|
+ rrs = edns.rrset.get(hostname, zoneOrigin=C.DNS_DOMAIN + ".")
|
|
|
+ rrs.rrList["CCMRRItem"].append({"rdata": txt_record, "rrClass": "IN", "rrType": "TXT"})
|
|
|
+ rrs.save()
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
+ os.environ["CPNR_USERNAME"] = CLEUCreds.CPNR_USERNAME
|
|
|
+ os.environ["CPNR_PASSWORD"] = CLEUCreds.CPNR_PASSWORD
|
|
|
+
|
|
|
print("Content-type: application/json\r\n\r\n")
|
|
|
|
|
|
output = sys.stdin.read()
|
|
@@ -206,6 +175,8 @@ if __name__ == "__main__":
|
|
|
txt = msg["text"]
|
|
|
found_hit = False
|
|
|
|
|
|
+ edns = ElementalDns()
|
|
|
+
|
|
|
if re.search(r"\bhelp\b", txt, re.I):
|
|
|
spark.post_to_spark(
|
|
|
C.WEBEX_TEAM,
|
|
@@ -222,12 +193,12 @@ if __name__ == "__main__":
|
|
|
if message_from not in ALLOWED_TO_CREATE:
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "I'm sorry, {}. I can't do that for you.".format(message_from))
|
|
|
else:
|
|
|
- res = check_for_alias(m.group(3))
|
|
|
+ res = check_for_alias(edns, m.group(3))
|
|
|
if res is None:
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "I didn't find an alias {}".format(m.group(3)))
|
|
|
else:
|
|
|
try:
|
|
|
- delete_alias(m.group(3))
|
|
|
+ delete_alias(res)
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "Alias {} deleted successfully.".format(m.group(3)), MessageType.GOOD)
|
|
|
except Exception as e:
|
|
|
spark.post_to_spark(
|
|
@@ -241,12 +212,12 @@ if __name__ == "__main__":
|
|
|
if message_from not in ALLOWED_TO_CREATE:
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "I'm sorry, {}. I can't do that for you.".format(message_from))
|
|
|
else:
|
|
|
- res = check_for_record(m.group(2))
|
|
|
+ res = check_for_record(edns, m.group(2))
|
|
|
if res is None:
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "I didn't find a DNS record for {}.".format(m.group(2)))
|
|
|
else:
|
|
|
try:
|
|
|
- delete_record(m.group(2))
|
|
|
+ delete_record(edns, res)
|
|
|
spark.post_to_spark(
|
|
|
C.WEBEX_TEAM, SPARK_ROOM, "DNS record for {} deleted successfully.".format(m.group(2)), MessageType.GOOD
|
|
|
)
|
|
@@ -265,13 +236,13 @@ if __name__ == "__main__":
|
|
|
if message_from not in ALLOWED_TO_CREATE:
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "I'm sorry, {}. I can't do that for you.".format(message_from))
|
|
|
else:
|
|
|
- res = check_for_record(m.group(2))
|
|
|
+ res = check_for_record(edns, m.group(2))
|
|
|
if res is not None:
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "_{}_ is already in DNS as **{}**".format(m.group(2), res["ip"]))
|
|
|
else:
|
|
|
hostname = re.sub(r"\.{}".format(C.DNS_DOMAIN), "", m.group(2))
|
|
|
try:
|
|
|
- create_record(m.group(2), m.group(3), m.group(8), message_from)
|
|
|
+ create_record(edns, m.group(2), m.group(3), m.group(8), message_from)
|
|
|
spark.post_to_spark(
|
|
|
C.WEBEX_TEAM, SPARK_ROOM, "Successfully created record for {}.".format(m.group(2)), MessageType.GOOD
|
|
|
)
|
|
@@ -291,7 +262,7 @@ if __name__ == "__main__":
|
|
|
alist = aliases.split(",")
|
|
|
already_exists = False
|
|
|
for alias in alist:
|
|
|
- res = check_for_alias(alias)
|
|
|
+ res = check_for_alias(edns, alias)
|
|
|
if res is not None:
|
|
|
already_exists = True
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "_{}_ is already an alias for **{}**".format(alias, res["hostname"]))
|
|
@@ -304,7 +275,7 @@ if __name__ == "__main__":
|
|
|
success = True
|
|
|
for alias in alist:
|
|
|
try:
|
|
|
- create_alias(m.group(8), alias)
|
|
|
+ create_alias(edns, m.group(8), alias)
|
|
|
except Exception as e:
|
|
|
spark.post_to_spark(C.WEBEX_TEAM, SPARK_ROOM, "Failed to create alias {}: {}".format(alias, e), MessageType.BAD)
|
|
|
success = False
|