예제 #1
0
class Tetration_Helper(object):
    class Inventory(object):
        offset = ''
        pagedData = None
        hasNext = False

    def __init__(self,
                 endpoint,
                 api_key,
                 api_secret,
                 pigeon,
                 options,
                 tenant_app_scope="Default"):
        self.rc = RestClient(endpoint,
                             api_key=api_key,
                             api_secret=api_secret,
                             verify=False)
        self.scopes = []
        self.pigeon = pigeon
        self.inventory = self.Inventory()
        self.filters = {}
        self.options = options
        self.subnets = []
        self.boolean = Boolean_Helper()
        self.tenant_app_scope = tenant_app_scope

    def GetSearchDimensions(self):
        resp = self.rc.get('/inventory/search/dimensions')
        return resp.json()

    def GetApplicationScopes(self):
        resp = self.rc.get('/app_scopes')
        if resp.status_code != 200:
            self.pigeon.status_code = '403'
            self.pigeon.note.update({
                'status_code': 403,
                'message':
                'Unable to get application scopes from tetration cluster',
                'data': {}
            })
            self.pigeon.send()
            exit(0)

        else:
            self.scopes = resp.json()

    def GetTenantNames(self):
        resp = self.rc.get('/vrfs')
        if resp.status_code != 200:
            self.pigeon.status_code = '403'
            self.pigeon.note.update({
                'status_code': 403,
                'message':
                'Unable to get application scopes from tetration cluster',
                'data': {}
            })
            self.pigeon.send()
            exit(0)

        else:
            return resp.json()

    def GetInventory(self, filters=None, dimensions=None):
        req_payload = {
            "filter": {
                "type": "or",
                "filters": filters
            },
            "scopeName": self.tenant_app_scope,
            "dimensions": dimensions,
            "limit": self.options["limit"],
            "offset": self.inventory.offset if self.inventory else ""
        }
        resp = self.rc.post('/inventory/search',
                            json_body=json.dumps(req_payload))
        if resp.status_code != 200:
            self.pigeon.note.update({
                'status_code': 403,
                'message': 'Unable to get inventory from tetration cluster',
                'data': {}
            })
            self.pigeon.send()
            exit(0)
        else:
            self.pigeon.note.update({
                'status_code': 100,
                'message':
                'Successfully retrieved inventory page from Tetration',
                'data': {}
            })
            self.pigeon.send()
            resp = resp.json()
            self.inventory.pagedData = resp['results']
            self.inventory.offset = resp['offset'] if 'offset' in resp else ''
            self.inventory.hasNext = True if self.inventory.offset else False
            return

    def CreateInventoryFilters(self, network_list):
        inventoryDict = {}
        appScopeId = json.loads(os.environ['FILTERS_APP_SCOPE_ID'])[0]["value"]
        for row in network_list:
            if row['comment'] not in inventoryDict:
                inventoryDict[row['comment']] = {}
                inventoryDict[row['comment']]['app_scope_id'] = appScopeId
                inventoryDict[row['comment']]['name'] = row['comment']
                inventoryDict[row['comment']][
                    'primary'] = "TRUE" if self.boolean.GetBoolean(
                        os.getenv('SCOPE_RESTRICTED',
                                  default=False)) else "FALSE"
                inventoryDict[row['comment']]['query'] = {
                    "type": "or",
                    "filters": []
                }
            inventoryDict[row['comment']]['query']['filters'].append({
                "type":
                "subnet",
                "field":
                "ip",
                "value":
                row['network']
            })
        self.filters = inventoryDict
        return

    def PushInventoryFilters(self):
        for inventoryFilter in self.filters:
            req_payload = self.filters[inventoryFilter]
            resp = self.rc.post('/filters/inventories',
                                json_body=json.dumps(req_payload))
            if resp.status_code != 200:
                self.pigeon.note.update({
                    'status_code': 403,
                    'message':
                    'Error pushing inventory filters to tetration cluster',
                    'data': {}
                })
                self.pigeon.send()
                return
        self.pigeon.note.update({
            'status_code': 100,
            'message':
            'Successfully posted inventory filters to Tetration cluster',
            'data': {}
        })
        self.pigeon.send()
        return

    def AnnotateHosts(self, hosts, columns, csvFile):
        with open(csvFile, "wb") as csv_file:
            fieldnames = ['IP']
            for column in columns:
                if column["infobloxName"] != 'extattrs':
                    fieldnames.extend([column["annotationName"]])
                else:
                    if column["overload"] == "on":
                        fieldnames.extend([column["annotationName"]])
                    else:
                        for attr in column["attrList"]:
                            fieldnames.extend([
                                str(column["annotationName"]) + '-' + str(attr)
                            ])
            writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
            writer.writeheader()
            for host in hosts:
                hostDict = {}
                hostDict["IP"] = host["ip_address"]
                # hostDict["VRF"] = [ tetHost["vrf_name"] for tetHost in self.inventory.pagedData if tetHost["ip"] == host["ip_address"] ][0]
                if len(host["names"]) < 1:
                    continue
                for column in columns:
                    if column["infobloxName"] == 'extattrs':
                        for attr in column["attrList"]:
                            if column["overload"] == "on":
                                if attr["value"] in host["extattrs"]:
                                    hostDict[column["annotationName"]] = str(
                                        attr["value"]
                                    ) + '=' + str(
                                        host["extattrs"][
                                            attr["value"]]["value"]
                                    ) + ';' if column[
                                        "annotationName"] not in hostDict.keys(
                                        ) else hostDict[
                                            column["annotationName"]] + str(
                                                attr["value"]
                                            ) + '=' + str(host["extattrs"][
                                                attr["value"]]["value"]) + ';'
                                else:
                                    hostDict[column["annotationName"]] = str(
                                        attr["value"]
                                    ) + '=;' if column[
                                        "annotationName"] not in hostDict.keys(
                                        ) else str(hostDict[
                                            column["annotationName"]]) + str(
                                                attr["value"]) + '=;'
                            else:
                                if attr["value"] in host["extattrs"]:
                                    hostDict[column["annotationName"] + '-' +
                                             attr["value"]] = host["extattrs"][
                                                 attr["value"]]["value"]
                                else:
                                    hostDict[column["annotationName"] + '-' +
                                             attr["value"]] = ''
                    elif column["infobloxName"] == 'zone':
                        hostDict[column["annotationName"]] = '.'.join(",".join(
                            host["names"]).split('.')[1:])
                    elif column["infobloxName"] == 'names':
                        hostDict[column["annotationName"]] = ",".join(
                            host[column["infobloxName"]]).split('.')[0]
                    else:
                        hostDict[column["annotationName"]] = host[
                            column["infobloxName"]]
                writer.writerow(hostDict)
        #keys = ['IP', 'VRF']
        #req_payload = [tetpyclient.MultiPartOption(key='X-Tetration-Key', val=keys), tetpyclient.MultiPartOption(key='X-Tetration-Oper', val='add')]
        #resp = self.rc.upload(csvFile, '/assets/cmdb/upload', req_payload)
        req_payload = [
            tetpyclient.MultiPartOption(key='X-Tetration-Oper', val='add')
        ]
        resp = self.rc.upload(csvFile,
                              '/assets/cmdb/upload/' + self.tenant_app_scope,
                              req_payload)
        if resp.status_code != 200:
            self.pigeon.note.update({
                'status_code': 403,
                'message': 'Error posting annotations to Tetration cluster',
                'data': {}
            })
            self.pigeon.send()
            return
        else:
            self.pigeon.note.update({
                'status_code': 100,
                'message':
                'Successfully posted annotations to Tetration cluster',
                'data': {}
            })
            self.pigeon.send()

    def AddSubnets(self, subnets):
        for subnet in subnets:
            self.subnets.append(IPNetwork(subnet))

    def HasSubnetFilterForIp(self, ip):
        for subnet in self.subnets:
            addr = IPAddress(ip)
            if subnet.__contains__(addr) is True or addr.is_private(
            ) is not True:
                return True
        return False