<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: RESTAPI call for Dynamic Address Group members in Panorama Discussions</title>
    <link>https://live.paloaltonetworks.com/t5/panorama-discussions/restapi-call-for-dynamic-address-group-members/m-p/579269#M2206</link>
    <description>&lt;P&gt;I have implemented a workaround solution by monitoring the ip tag logs using the XML api.&lt;BR /&gt;I'm dumping my code here, this can be used as a starting point for your own use-case.&lt;BR /&gt;&lt;BR /&gt;I am still interested in having a way to monitor DAG members directly using the REST API. This way is, in my opinion, not elegant.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;import requests, re, datetime, xmltodict, time

pa_user = 'username'
pa_password = 'password'
panorama_url = 'panorama.domain'
pan_base_url = 'https://' + panorama_url

def generate_pa_key(fwl_dns=panorama_url):
    response = requests.get(
        'https://{0}/api/?type=keygen&amp;amp;user={1}&amp;amp;password={2}'.format(fwl_dns, pa_user, pa_password), verify=False)
    result = re.findall("&amp;lt;key&amp;gt;.*&amp;lt;/key&amp;gt;", response.text)
    key = result[0][5:-6]
    return key

def panorama_get(key, sub_url):
    header = {'X-PAN-Key': "{}".format(key)}    
    return requests.get(pan_base_url+sub_url, headers=header)

def get_ip_tag_logs():
    #generate panoramakey
    key = generate_pa_key(panorama_url)
    
    #generate correct time for query
    current_time = datetime.datetime.now()
    new_time = current_time - datetime.timedelta(minutes=9)
    formatted_time = new_time.strftime("%Y/%m/%d %H:%M:%S")
    
    #query on ip of monitoring VM, for firewall device-name
    query = "(ip in '10.10.10.10') and (device_name eq 'device-name') and (time_generated geq '{}') and (vsys eq 'vsys5')".format(formatted_time).replace(' ','%20')
    sub_url = 'api?type=log&amp;amp;log-type=iptag&amp;amp;query=' + query
    result = panorama_get(key, sub_url)
    
    if result.status_code != 200:
        #failure_reason = 'error: query job generation failed. {0}. {1}'.format(result,result.text)
        #add_failure(failure_reason)
        return False
    
    if result.status_code == 200:    
        job_id_dict = xmltodict.parse(result.text)
        job_id = job_id_dict['response']['result']['job'] 
        sub_url = '/api?type=log&amp;amp;action=get&amp;amp;job-id={}'.format(job_id)
        result = panorama_get(key,sub_url)
        #stop unending loops
        while_count = 0
        while result.status_code == 200:
            while_count += 1
            if while_count &amp;gt; 5:
                #add_failure('querying for logs took too long')
                break     
            if xmltodict.parse(result.text)['response']['result']['job']['status'] != 'FIN':
                time.sleep(10)
                result = panorama_get(key,sub_url)
            elif xmltodict.parse(result.text)['response']['result']['job']['status'] == 'FIN':
                return xmltodict.parse(result.text)['response']['result']['log']['logs']
    else:
        return -1&lt;/LI-CODE&gt;</description>
    <pubDate>Tue, 05 Mar 2024 09:46:21 GMT</pubDate>
    <dc:creator>T_Hoedemaekers</dc:creator>
    <dc:date>2024-03-05T09:46:21Z</dc:date>
    <item>
      <title>RESTAPI call for Dynamic Address Group members</title>
      <link>https://live.paloaltonetworks.com/t5/panorama-discussions/restapi-call-for-dynamic-address-group-members/m-p/578866#M2197</link>
      <description>&lt;P&gt;For one of my automation use-cases I need to check what IP's are a member of a Dynamic Address Group, this list:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="T_Hoedemaekers_0-1709225550790.png" style="width: 400px;"&gt;&lt;img src="https://live.paloaltonetworks.com/t5/image/serverpage/image-id/57950i8D8176CAFCD300B3/image-size/medium/is-moderation-mode/true?v=v2&amp;amp;px=400" role="button" title="T_Hoedemaekers_0-1709225550790.png" alt="T_Hoedemaekers_0-1709225550790.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;I haven't found an API request that results in this data. I know I will be able to grab the data from cli but ssh'ing into panorama is a solution I try to avoid.&lt;/P&gt;
&lt;P&gt;Using /restapi/v10.2/Objects/AddressGroups I receive the filter as output, not the membership:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;DIV style="color: #000000; background-color: #ffffff; font-family: IBMPlexMono, 'Courier New', monospace, Consolas, 'Courier New', monospace; font-weight: normal; font-size: 12px; line-height: 18px; white-space: pre;"&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;"@name"&lt;/SPAN&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN&gt;"ACI-TEST_Monitoring_Monitoring1"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;"@location"&lt;/SPAN&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN&gt;"device-group"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;"@device-group"&lt;/SPAN&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN&gt;"**"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;"@loc"&lt;/SPAN&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN&gt;"**"&lt;/SPAN&gt;&lt;SPAN&gt;,&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;"dynamic"&lt;/SPAN&gt;&lt;SPAN&gt;: {&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;"filter"&lt;/SPAN&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN&gt;"'**.tn_TEST.ap_Monitoring.epg_Monitoring1'"&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;&lt;BR /&gt;Am I missing something? Is there a way to get this data via the rest API?&lt;BR /&gt;And if not, is there a way to request this as a feature in a future panorama release?&lt;/P&gt;</description>
      <pubDate>Thu, 29 Feb 2024 16:55:15 GMT</pubDate>
      <guid>https://live.paloaltonetworks.com/t5/panorama-discussions/restapi-call-for-dynamic-address-group-members/m-p/578866#M2197</guid>
      <dc:creator>T_Hoedemaekers</dc:creator>
      <dc:date>2024-02-29T16:55:15Z</dc:date>
    </item>
    <item>
      <title>Re: RESTAPI call for Dynamic Address Group members</title>
      <link>https://live.paloaltonetworks.com/t5/panorama-discussions/restapi-call-for-dynamic-address-group-members/m-p/579269#M2206</link>
      <description>&lt;P&gt;I have implemented a workaround solution by monitoring the ip tag logs using the XML api.&lt;BR /&gt;I'm dumping my code here, this can be used as a starting point for your own use-case.&lt;BR /&gt;&lt;BR /&gt;I am still interested in having a way to monitor DAG members directly using the REST API. This way is, in my opinion, not elegant.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;import requests, re, datetime, xmltodict, time

pa_user = 'username'
pa_password = 'password'
panorama_url = 'panorama.domain'
pan_base_url = 'https://' + panorama_url

def generate_pa_key(fwl_dns=panorama_url):
    response = requests.get(
        'https://{0}/api/?type=keygen&amp;amp;user={1}&amp;amp;password={2}'.format(fwl_dns, pa_user, pa_password), verify=False)
    result = re.findall("&amp;lt;key&amp;gt;.*&amp;lt;/key&amp;gt;", response.text)
    key = result[0][5:-6]
    return key

def panorama_get(key, sub_url):
    header = {'X-PAN-Key': "{}".format(key)}    
    return requests.get(pan_base_url+sub_url, headers=header)

def get_ip_tag_logs():
    #generate panoramakey
    key = generate_pa_key(panorama_url)
    
    #generate correct time for query
    current_time = datetime.datetime.now()
    new_time = current_time - datetime.timedelta(minutes=9)
    formatted_time = new_time.strftime("%Y/%m/%d %H:%M:%S")
    
    #query on ip of monitoring VM, for firewall device-name
    query = "(ip in '10.10.10.10') and (device_name eq 'device-name') and (time_generated geq '{}') and (vsys eq 'vsys5')".format(formatted_time).replace(' ','%20')
    sub_url = 'api?type=log&amp;amp;log-type=iptag&amp;amp;query=' + query
    result = panorama_get(key, sub_url)
    
    if result.status_code != 200:
        #failure_reason = 'error: query job generation failed. {0}. {1}'.format(result,result.text)
        #add_failure(failure_reason)
        return False
    
    if result.status_code == 200:    
        job_id_dict = xmltodict.parse(result.text)
        job_id = job_id_dict['response']['result']['job'] 
        sub_url = '/api?type=log&amp;amp;action=get&amp;amp;job-id={}'.format(job_id)
        result = panorama_get(key,sub_url)
        #stop unending loops
        while_count = 0
        while result.status_code == 200:
            while_count += 1
            if while_count &amp;gt; 5:
                #add_failure('querying for logs took too long')
                break     
            if xmltodict.parse(result.text)['response']['result']['job']['status'] != 'FIN':
                time.sleep(10)
                result = panorama_get(key,sub_url)
            elif xmltodict.parse(result.text)['response']['result']['job']['status'] == 'FIN':
                return xmltodict.parse(result.text)['response']['result']['log']['logs']
    else:
        return -1&lt;/LI-CODE&gt;</description>
      <pubDate>Tue, 05 Mar 2024 09:46:21 GMT</pubDate>
      <guid>https://live.paloaltonetworks.com/t5/panorama-discussions/restapi-call-for-dynamic-address-group-members/m-p/579269#M2206</guid>
      <dc:creator>T_Hoedemaekers</dc:creator>
      <dc:date>2024-03-05T09:46:21Z</dc:date>
    </item>
  </channel>
</rss>

