{"id":1720,"date":"2023-02-02T13:45:18","date_gmt":"2023-02-02T18:45:18","guid":{"rendered":"https:\/\/enterpriseadmins.org\/blog\/?p=1720"},"modified":"2023-02-02T15:51:41","modified_gmt":"2023-02-02T20:51:41","slug":"learn-how-to-monitor-pi-hole-with-vrops-using-the-management-pack-builder","status":"publish","type":"post","link":"https:\/\/enterpriseadmins.org\/blog\/virtualization\/learn-how-to-monitor-pi-hole-with-vrops-using-the-management-pack-builder\/","title":{"rendered":"Learn how to monitor Pi-hole with vROps using the Management Pack Builder"},"content":{"rendered":"\n<p>First of all, thank you to Brian for allowing me to make my first post of what will hopefully be more on EnterpriseAdmins. As a quick introduction, I am a Staff Technical Account Manager at VMware and live near Cleveland, OH.<\/p>\n\n\n\n<p>I recently set out to learn about the VMware Aria Operations Management Pack Builder, which I will abbreviate as MPB for brevity, and in this article, I will bring you along on my learning journey. I found the <a href=\"https:\/\/communities.vmware.com\/t5\/Management-Pack-Builder\/ct-p\/13006\">Communities <\/a>page to be a good starting point as there were links to the appliance download as well as documentation and other learning tools. And I\u2019ll put it out there now that much of the \u201cfiguring out\u201d that occurs through the article was greatly aided by Brian\u2019s help.<\/p>\n\n\n\n<p>The MPB is described in the <a href=\"https:\/\/docs.vmware.com\/en\/VMware-vRealize-Operations-Management-Pack-Builder\/1.0.0\/management-pack-builder\/GUID-1C363DCE-5C4A-473D-A519-A55E0371A9F2.html#before-you-start-a-design-1\">documentation <\/a>as a no-code stand-alone appliance that enables the creation of custom management packs for vRealize (Aria) Operations Manager (henceforth referred to as vROps), allowing you to collect data  from an external API to to then create or extend resources in vROps with new Data, Relationships, and Events where VMware, or another vendor, has not released an official management pack.<\/p>\n\n\n\n<p>With a basic understanding of what the MPB did, I started looking for an application that was already running in my lab that had both API functionality and interesting content already, and settled on Pi-hole, an ad blocking DNS server. If you don&#8217;t already have Pi-hole deployed, you can use Brian&#8217;s deployment instructions <a href=\"https:\/\/enterpriseadmins.org\/blog\/lab-infrastructure\/setting-up-pi-hole-dns\/\">here<\/a>. An Internet search showed me that Pi-hole uses \u201cfqdn\/admin\/api.php\u201d as the base for API calls and brought me to <a href=\"https:\/\/discourse.pi-hole.net\/t\/pi-hole-api\/1863\">this page<\/a> which gave enough examples of the Pi-hole API to get started (as a side note, the API structure is not as far along as I would have guessed. We\u2019ll see an example of a shortcoming later in this article).<\/p>\n\n\n\n<p>To explore the Pi-hole API, I started with the \u201ctype\u201d request as it does not require authentication. Since my pi-hole server is at 192.168.55.3 and I do not have a TLS certificate enabled, I entered <code>http:\/\/192.168.55.3\/admin\/api.php?type<\/code> into my browser and got a returned value of {&#8220;type&#8221;:&#8221;FTL&#8221;}. This was a good start. I then attempted both the summary and summaryRaw requests, which the document says does not require authorization but found that to not be the case.  I set out to determine how to authenticate to the API and found in the Pi-hole admin interface \/ Settings \/ API\/Web Interface section there is an option to \u201cShow API token\u201d, as shown here<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"752\" src=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1024x752.png\" alt=\"\" class=\"wp-image-1730\" srcset=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1024x752.png 1024w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-300x220.png 300w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-768x564.png 768w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1536x1129.png 1536w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image.png 1908w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Finding myPi-hole API token<\/figcaption><\/figure>\n\n\n\n<p> I recorded that token, which I\u2019ll call myAPIToken through the rest of the article, and after a bit of experimenting found that a URL of <code>http:\/\/192.168.55.3\/admin\/api.php?summary&amp;auth=myAPIToken<\/code> would return the correct dataset. An example of the data from a call to the summary API in my lab is:<br>{&#8220;domains_being_blocked&#8221;:173812,&#8221;dns_queries_today&#8221;:93557,&#8221;ads_blocked_today&#8221;:20121,&#8221;ads_percentage_today&#8221;:21.506676,&#8221;unique_domains&#8221;:14998,&#8221;queries_forwarded&#8221;:52135,&#8221;queries_cached&#8221;:20425,&#8221;clients_ever_seen&#8221;:42,&#8221;unique_clients&#8221;:26,&#8221;dns_queries_all_types&#8221;:93557,&#8221;reply_UNKNOWN&#8221;:1018,&#8221;reply_NODATA&#8221;:19198,&#8221;reply_NXDOMAIN&#8221;:7366,&#8221;reply_CNAME&#8221;:29501,&#8221;reply_IP&#8221;:35897,&#8221;reply_DOMAIN&#8221;:149,&#8221;reply_RRNAME&#8221;:1,&#8221;reply_SERVFAIL&#8221;:10,&#8221;reply_REFUSED&#8221;:0,&#8221;reply_NOTIMP&#8221;:0,&#8221;reply_OTHER&#8221;:0,&#8221;reply_DNSSEC&#8221;:0,&#8221;reply_NONE&#8221;:0,&#8221;reply_BLOB&#8221;:417,&#8221;dns_queries_all_replies&#8221;:93557,&#8221;privacy_level&#8221;:0,&#8221;status&#8221;:&#8221;enabled&#8221;,&#8221;gravity_last_updated&#8221;:{&#8220;file_exists&#8221;:true,&#8221;absolute&#8221;:1674986048,&#8221;relative&#8221;:{&#8220;days&#8221;:1,&#8221;hours&#8221;:9,&#8221;minutes&#8221;:37}}}<\/p>\n\n\n\n<p>If you are newer to exploring API\u2019s, like I am, it will be useful to break down the various parts of the URL that we are going to need to understand when creating and testing\/troubleshooting our Management Pack Design.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>http:\/\/192.168.55.3<\/strong> \u2013 the key thing here is that we are using http and not https. This will drive our port and SSL configuration choices<\/li>\n\n\n\n<li><strong>\/admin\/api.php<\/strong> \u2013 Pi-hole uses this path to call an API<\/li>\n\n\n\n<li><strong>?<\/strong> \u2013 an indicator that we are passing in a value<\/li>\n\n\n\n<li><strong>summary <\/strong>\u2013 the name of the API request that we are using<\/li>\n\n\n\n<li><strong>&amp; <\/strong>&#8211; an indicator that there is a second value being passed<\/li>\n\n\n\n<li><strong>auth=myAPIToken<\/strong> \u2013 a key\/value pair that Pi-hole is expecting for an API request that requires authentication<\/li>\n<\/ul>\n\n\n\n<p>With sufficient information about the Pi-hole API, I turned to the MPB communities page noted earlier for the download and documentation links to install the appliance into my lab. Following the steps in the documentation, I deployed the MPB in my lab, accessed it via a browser, and set the admin password with no issues to call out.<\/p>\n\n\n\n<p>The documentation does a good job of explaining the main constructs of the Management Pack that we are going to build, defining the terms Design, Object, Requests, and Relationships. For my example of building a Pi-hole MP, I identified that the Pi-hole server was going to be my Object as I have two of those to work with, and that the summary API request was going to provide enough properties and metrics to have meaningful data for this experiment. This proved mostly true except for the hostname of my Pi-hole server, which will be detailed later.<\/p>\n\n\n\n<p>Using the <em>Creating a Design<\/em> section of the documentation as a guide, I began a new design. The thing that would have been easier had I understood from the start about the <em>Source<\/em> section of the design is that portions of it are for testing only, but some of it will become content in the actual MP that you build. I will note those sections below:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Edit the name from \u201cUntitled Design\u201d to \u201cPiHole Server\u201d\n<ul class=\"wp-block-list\">\n<li>This will be the name displayed in the Integrations\/Repository section of vROps.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In the Reference Environment Settings section:\n<ul class=\"wp-block-list\">\n<li>Hostname \u2013 192.168.55.3<\/li>\n\n\n\n<li>Port \u2013 80<\/li>\n\n\n\n<li>SSL Configuration \u2013 No SSL<\/li>\n\n\n\n<li>Base API Path \u2013 leave blank<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In the Authentication section:\n<ul class=\"wp-block-list\">\n<li>Authentication Source Type \u2013 Custom<\/li>\n\n\n\n<li>Add a Field\n<ul class=\"wp-block-list\">\n<li>Label \u2013 API token (this will become the prompt for the field where the MP user is prompted to provide their API token when setting up the Adapter)<\/li>\n\n\n\n<li>Value \u2013 myAPIToken<\/li>\n\n\n\n<li>Sensitive box \u2013 checked<br>This section took me a minute to understand that you are creating a variable, that in my case is called <code>${authentication.credentials.api_token}<\/code> that you then use later in place of the auth token. This value will become part of the MP<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Nothing in the Global Request Settings section<\/li>\n\n\n\n<li>Advanced Request Settings\n<ul class=\"wp-block-list\">\n<li>Add a Query Parameter (this will become part of the MP)\n<ul class=\"wp-block-list\">\n<li>Key \u2013 auth<\/li>\n\n\n\n<li>Value &#8211; ${authentication.credentials.api_token}\n<ul class=\"wp-block-list\">\n<li>This is copied from the Authentication section above<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Add a Query Parameter (this is only used to validate the Reference environment and will not be carried into the MP)\n<ul class=\"wp-block-list\">\n<li>Key \u2013 summary<\/li>\n\n\n\n<li>Value \u2013 True (the UI requires us to enter a value, even though the API request doesn\u2019t require this)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Make Request section (this section is only for testing your reference environment)\n<ul class=\"wp-block-list\">\n<li>HTTP Method \u2013 Get<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Test Request Path \u2013 admin\/api.php<\/li>\n<\/ul>\n\n\n\n<p>The URL Preview should look like:<br><em>http:\/\/192.168.55.3:80\/admin\/api.php?auth=%24%7Bauthentication.credentials.api_token%7D&amp;summary=true<\/em><br>This should look very much like the test we performed earlier, except for our token being replaced by the variable <em>%24%7Bauthentication.credentials.api_token%7D<\/em><br>When you click the Test button you should see a green box that says, \u201cSuccessfully connected\u201d and a <em>Check Response<\/em> link that when you click it displays the results of the summary request. If you don\u2019t get data successfully returned here, compare the URL Preview very carefully to the URL you tested earlier to identify the difference.<\/p>\n\n\n\n<p>With a <em>Source <\/em>section successfully tested against our reference environment, we move to the <em>Requests <\/em>section of the design. As the documentation describes, this is where we define the API requests that we need to collect the data that our MP uses. We are going to create two requests, one named \u201csummary\u201d and one named \u201chostname\u201d. Let\u2019s work through these one at a time.<\/p>\n\n\n\n<p>We determined early on that the summary API request was going to return most of the data that we would use in our MP. And we used it in our <em>Source <\/em>section to test our reference environment. If you looked at the results of the summary request carefully, you would note that the results do not include the actual hostname of your Pi-hole server. And in fact, there is not an API request that will return the name of your Pi-hole server. If we only have one Pi-hole server this wouldn\u2019t be a horrible problem in vROps, but if we have multiple servers that we want to monitor, there\u2019s not a reliable value to identify which server is which. So, Brian came up with the following clever solution that requires a script to be created on each Pi-hole server but then allows the hostname of the server to be collected:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>SSH to your Pi-hole server with a privileged account (in my case \u201cpi\u201d) with the password that you set on that account<\/li>\n\n\n\n<li>Create a new file <em>\/var\/www\/html\/get-hostname.php<\/em> with the following content:<br><code>&lt;?php echo '{\"hostname\":\"' . gethostname() . '\"}'; ?&gt;<\/code><\/li>\n<\/ol>\n\n\n\n<p>If you\u2019re not comfortable with linux commands, you could copy or type the following to create the get-hostname.php file:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>sudo nano \/var\/www\/html\/get-hostname.php\n<ul class=\"wp-block-list\">\n<li>this creates the file and opens it in the nano editor<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>paste the line of code from above<\/li>\n\n\n\n<li>Ctrl+X to Exit<\/li>\n\n\n\n<li>Press Y to save the modified buffer<\/li>\n\n\n\n<li>Press Enter to write to  the file<\/li>\n<\/ol>\n\n\n\n<p>With this file created, we can go back to the MPB UI and define the first request that will return data for our MP by clicking the Add Request button then:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Change the name from API Request to hostname<\/li>\n\n\n\n<li>Chain from another API request \u2013 no change<\/li>\n\n\n\n<li>Resource Path\n<ul class=\"wp-block-list\">\n<li>get-hostname.php<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Advanced \u2013 no change<\/li>\n\n\n\n<li>Get data<br>With an HTTP Method of Get, the Preview should look like <em>http:\/\/192.168.55.3:80\/get-hostname.php<\/em> and when you click the Request button, should return your Pi-hole server name. We can now click Add Request to create our second request. <\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Change the name from API Request to summary<\/li>\n\n\n\n<li>Chain from another API request \u2013 no change<\/li>\n\n\n\n<li>Resource Path\n<ul class=\"wp-block-list\">\n<li>admin\/api.php<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Advanced\n<ul class=\"wp-block-list\">\n<li>Body and Headers \u2013 no change<\/li>\n\n\n\n<li>Query Parameters\n<ul class=\"wp-block-list\">\n<li>First Parameter\n<ul class=\"wp-block-list\">\n<li>Key \u2013 summary<\/li>\n\n\n\n<li>Value \u2013 true<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Second Parameter\n<ul class=\"wp-block-list\">\n<li>Key \u2013 auth<\/li>\n\n\n\n<li>Value &#8211; ${authentication.credentials.api_token}\n<ul class=\"wp-block-list\">\n<li>This is the variable that we defined in the Source section<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Get data<br>With an HTTP Method of Get, the <em>Preview <\/em>should match what we saw in the Source section and when you click the Request button, should return a dataset.<\/li>\n<\/ul>\n\n\n\n<p>Now that we have defined the Requests, we move to the <em>Objects<\/em> section of our design where we can select the data from the API requests that we\u2019d like to include in our MP. Click the <em>Add New Object<\/em> button and populate it as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Change the name to PiHole Server<\/li>\n\n\n\n<li>Metrics and Properties from API Request\n<ul class=\"wp-block-list\">\n<li>Click the &lt;&lt; next to summary and select the metrics that you\u2019d like to collect with vROps. Note as you hover over the names, you will see a value that was obtained when you tested the request in the previous section. At a minimum I would suggest:\n<ul class=\"wp-block-list\">\n<li>ads_blocked_today<\/li>\n\n\n\n<li>ads_percentage_today<\/li>\n\n\n\n<li>status<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Click the &lt;&lt; next to hostname and select \u2018hostname\u2019<\/li>\n\n\n\n<li>Scroll down and make the following changes to the chart:\n<ul class=\"wp-block-list\">\n<li>Hostname \u2013 leave as is<\/li>\n\n\n\n<li>ads_blocked_today\n<ul class=\"wp-block-list\">\n<li>disable Property<\/li>\n\n\n\n<li>Set Data Type to DECIMAL<\/li>\n\n\n\n<li>Set Unit to Count<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>ads_percentage_today\n<ul class=\"wp-block-list\">\n<li>disable Property<\/li>\n\n\n\n<li>Set Data Type to DECIMAL<\/li>\n\n\n\n<li>Set Unit to %<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Status \u2013 leave as is<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Object name, Identifier, and Icon\n<ul class=\"wp-block-list\">\n<li>Select object instance name \u2013 hostname<\/li>\n\n\n\n<li>Select object identifiers \u2013 hostname<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>The results will look as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"449\" src=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-2-1024x449.png\" alt=\"\" class=\"wp-image-1765\" srcset=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-2-1024x449.png 1024w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-2-300x132.png 300w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-2-768x337.png 768w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-2-1536x674.png 1536w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-2-2048x899.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Objects section in Management Pack Builder<\/figcaption><\/figure>\n\n\n\n<p>There are no <em>Relationships <\/em>to define, and we are not going to create any <em>Events <\/em>for this example so we can select the <em>Configuration <\/em>section where we can review and modify MP version as well as labels and default values for various fields. With this information complete, click the <em>Save <\/em>button near the top of the Design then click the <em>Build <\/em>button. Review the Identifiers and Properties and since we didn\u2019t define Relationships or Events, click Next. Click the Perform Collection button to collect sample data and review the Collection Summary to ensure the results were as expected then click Next. Lastly, click the Build button to create the MP. Look for the Build succeeded message then click the Go to build link. Click the name\/version of the MP which is a link that will start the download of the .pak file. Save this file and you are now ready to import it into vROps.<\/p>\n\n\n\n<p>Installing the resulting .pak file is done like any other MP, from Data Sources \/ Integrations \/ Repositories with the exception that you will have to check the box to \u201cIgnore the PAK file signature checking\u201d as this MP is not signed.  Once the MP is installed, you add an Account for each of your Pi-hole, which will include adding Credentials to vROps that is the API token for your server. Before long, you too can track your Pi-hole performance in vROps.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"513\" src=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1-1024x513.png\" alt=\"\" class=\"wp-image-1732\" srcset=\"https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1-1024x513.png 1024w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1-300x150.png 300w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1-768x384.png 768w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1-1536x769.png 1536w, https:\/\/enterpriseadmins.org\/blog\/wp-content\/uploads\/2023\/02\/image-1-2048x1025.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Collecting Pi-hole metrics in VMware Aria Operations Manager<\/figcaption><\/figure>\n\n\n\n<p>I&#8217;d love for you to leave a comment below with what other apps you build a management pack for.<br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to build a vROps Management Pack to collect data about your Pi-hole servers <a href=\"https:\/\/enterpriseadmins.org\/blog\/virtualization\/learn-how-to-monitor-pi-hole-with-vrops-using-the-management-pack-builder\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[9,4],"tags":[],"class_list":["post-1720","post","type-post","status-publish","format-standard","hentry","category-lab-infrastructure","category-virtualization"],"_links":{"self":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1720","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/comments?post=1720"}],"version-history":[{"count":39,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1720\/revisions"}],"predecessor-version":[{"id":1769,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/posts\/1720\/revisions\/1769"}],"wp:attachment":[{"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/media?parent=1720"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/categories?post=1720"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/enterpriseadmins.org\/blog\/wp-json\/wp\/v2\/tags?post=1720"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}