Dns analytics report (#121)

* Add DNS Analytics report endpoint


Add DNS Analytics report endpoint


Add DNS Analytics report endpoint

* Remove useless response error test

* Add tests for DNS analytics report class methods

* Implement methods for listing grouped by time metrics report
This commit is contained in:
Constantin Cuciurcă
2020-07-07 13:17:48 +03:00
committed by GitHub
parent 06de5b0c04
commit ffc3989607
6 changed files with 372 additions and 2 deletions

View File

@@ -12,6 +12,7 @@ The Cloudflare API can be found [here](https://api.cloudflare.com/).
Each API call is provided via a similarly named function within various classes in the **Cloudflare\API\Endpoints** namespace:
- [x] [DNS Records](https://www.cloudflare.com/dns/)
- [x] [DNS Analytics](https://api.cloudflare.com/#dns-analytics-table)
- [x] Zones
- [x] User Administration (partial)
- [x] [Cloudflare IPs](https://www.cloudflare.com/ips/)
@@ -37,7 +38,7 @@ Note that this repository is currently under development, additional classes and
$key = new Cloudflare\API\Auth\APIKey('user@example.com', 'apiKey');
$adapter = new Cloudflare\API\Adapter\Guzzle($key);
$user = new Cloudflare\API\Endpoints\User($adapter);
echo $user->getUserID();
```
@@ -45,6 +46,6 @@ echo $user->getUserID();
We welcome community contribution to this repository. [CONTRIBUTING.md](CONTRIBUTING.md) will help you start contributing.
## Licensing
## Licensing
Licensed under the 3-clause BSD license. See the [LICENSE](LICENSE) file for details.

View File

@@ -0,0 +1,69 @@
<?php
namespace Cloudflare\API\Configurations;
class DNSAnalytics implements Configurations
{
protected $configs = [];
public function getArray(): array
{
return $this->configs;
}
public function setDimensions(array $dimensions)
{
if (count($dimensions) !== 0) {
$this->configs['dimensions'] = implode(',', $dimensions);
}
}
public function setMetrics(array $metrics)
{
if (count($metrics) !== 0) {
$this->configs['metrics'] = implode(',', $metrics);
}
}
public function setSince(string $since)
{
if ($since) {
$this->configs['since'] = $since;
}
}
public function setUntil(string $until)
{
if ($until) {
$this->configs['until'] = $until;
}
}
public function setSorting(array $sorting)
{
if (count($sorting) !== 0) {
$this->configs['sort'] = implode(',', $sorting);
}
}
public function setFilters(string $filters)
{
if ($filters) {
$this->configs['filters'] = $filters;
}
}
public function setLimit(int $limit)
{
if ($limit) {
$this->configs['limit'] = $limit;
}
}
public function setTimeDelta(string $timeDelta)
{
if ($timeDelta) {
$this->configs['time_delta'] = $timeDelta;
}
}
}

View File

@@ -0,0 +1,144 @@
<?php
/**
* Created by Visual Studio Code.
* User: elliot.alderson
* Date: 2020-02-06
* Time: 03:40 AM
*/
namespace Cloudflare\API\Endpoints;
use Cloudflare\API\Adapter\Adapter;
use Cloudflare\API\Traits\BodyAccessorTrait;
use Cloudflare\API\Configurations\DNSAnalytics as Configs;
class DNSAnalytics implements API
{
use BodyAccessorTrait;
private $adapter;
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
}
/**
* Retrieves a list of summarised aggregate metrics over a given time period.
*
* @param string $zoneID ID of zone to get report for
* @param string $dimensions Comma separated names of dimensions
* @param string $metrics Comma separated names of dimension to get metrics for
* @param string $sort Comma separated names of dimension to sort by prefixed by order - (descending) or + (ascending)
* @param string $filters Segmentation filter in 'attribute operator value' format
* @param string $since Start date and time of requesting data period in the ISO8601 format
* @param string $until End date and time of requesting data period in the ISO8601 format
* @param string $limit Limit number of returned metrics
* @return array
*/
public function getReportTable(
string $zoneID,
array $dimensions = [],
array $metrics = [],
array $sort = [],
string $filters = '',
string $since = '',
string $until = '',
int $limit = 100
): \stdClass {
if (count($dimensions) === 0) {
throw new EndpointException(
'At least one dimension is required for getting a report.'
);
}
if (count($metrics) === 0) {
throw new EndpointException(
'At least one metric is required for getting a report.'
);
}
if (!$since) {
throw new EndpointException(
'Start date is required for getting a report.'
);
}
if (!$until) {
throw new EndpointException(
'End date is required for getting a report.'
);
}
$options = [
'dimensions' => implode(',', $dimensions),
'metrics' => implode(',', $metrics),
'since' => $since,
'until' => $until
];
if (count($sort) !== 0) {
$options['sort'] = implode(',', $sort);
}
if ($filters) {
$options['filters'] = $filters;
}
if ($limit) {
$options['limit'] = $limit;
}
$endpoint = 'zones/' . $zoneID . '/dns_analytics/report';
$report = $this->adapter->get($endpoint, $options);
$this->body = json_decode($report->getBody());
return $this->body->result;
}
/**
* Retrieves a list of aggregate metrics grouped by time interval.
*
* @param string $zoneID ID of zone to get report for
* @param string $dimensions Comma separated names of dimensions
* @param string $metrics Comma separated names of dimension to get metrics for
* @param string $sort Comma separated names of dimension to sort by prefixed by order - (descending) or + (ascending)
* @param string $filters Segmentation filter in 'attribute operator value' format
* @param string $since Start date and time of requesting data period in the ISO8601 format
* @param string $until End date and time of requesting data period in the ISO8601 format
* @param string $limit Limit number of returned metrics
* @param string $timeDelta Unit of time to group data by
* @return array
*/
public function getReportByTime(
string $zoneID,
array $dimensions = [],
array $metrics = [],
array $sort = [],
string $filters = '',
string $since = '',
string $until = '',
int $limit = 100,
string $timeDelta = ''
): \stdClass {
$options = new Configs();
$options->setDimensions($dimensions);
$options->setMetrics($metrics);
$options->setSince($since);
$options->setUntil($until);
$options->setSorting($sort);
$options->setFilters($filters);
$options->setLimit($limit);
$options->setTimeDelta($timeDelta);
$endpoint = 'zones/' . $zoneID . '/dns_analytics/report/bytime';
$report = $this->adapter->get($endpoint, $options->getArray());
$this->body = json_decode($report->getBody());
return $this->body->result;
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* Created by Visual Studio Code.
* User: elliot.alderson
* Date: 10/02/2020
* Time: 04:28 AM
*/
class DNSAnalyticsTest extends TestCase
{
public function testGetDNSAnalyticsReportTable()
{
$response = $this->getPsr7JsonResponseForFixture(
'Endpoints/getDNSAnalyticsReportTable.json'
);
$mock = $this->getMockBuilder(
\Cloudflare\API\Adapter\Adapter::class
)->getMock();
$mock->method('get')->willReturn($response);
$mock
->expects($this->once())
->method('get')
->with(
$this->equalTo(
'zones/023e105f4ecef8ad9ca31a8372d0c353/dns_analytics/report'
)
);
$analytics = new \Cloudflare\API\Endpoints\DNSAnalytics($mock);
$since = '2020-02-01T00:00:00Z';
$until = '2020-02-28T23:59:59Z';
$filters = 'responseCode==NOERROR AND queryType==A';
$result = $analytics->getReportTable(
'023e105f4ecef8ad9ca31a8372d0c353',
['queryName', 'queryType', 'responseCode'],
['queryCount'],
['-queryCount'],
$filters,
$since,
$until
);
$this->assertEquals(1, $result->rows);
$this->assertEquals($since, $result->query->since);
$this->assertEquals($until, $result->query->until);
}
public function testGetDNSAnalyticsReportByTime()
{
$response = $this->getPsr7JsonResponseForFixture(
'Endpoints/getDNSAnalyticsReportByTime.json'
);
$mock = $this->getMockBuilder(
\Cloudflare\API\Adapter\Adapter::class
)->getMock();
$mock->method('get')->willReturn($response);
$mock
->expects($this->once())
->method('get')
->with(
$this->equalTo(
'zones/023e105f4ecef8ad9ca31a8372d0c353/dns_analytics/report/bytime'
)
);
$analytics = new \Cloudflare\API\Endpoints\DNSAnalytics($mock);
$since = '2020-02-01T00:00:00Z';
$until = '2020-02-28T23:59:59Z';
$filters = 'responseCode==NOERROR AND queryType==A';
$result = $analytics->getReportByTime(
'023e105f4ecef8ad9ca31a8372d0c353',
['queryName', 'queryType', 'responseCode'],
['queryCount'],
['-queryCount'],
$filters,
$since,
$until,
2
);
$this->assertEquals(2, $result->rows);
$this->assertEquals($since, $result->query->since);
$this->assertEquals($until, $result->query->until);
}
}

View File

@@ -0,0 +1,31 @@
{
"result": {
"rows": 2,
"data": [
{
"metrics": [[911, 993]]
}
],
"data_lag": 0,
"min": {},
"max": {},
"totals": {
"queryCount": 455312
},
"time_intervals": [
["2020-02-10T11:19:00Z", "2020-02-10T11:19:59Z"],
["2020-02-10T11:20:00Z", "2020-02-10T11:20:59Z"]
],
"query": {
"dimensions": [],
"metrics": ["queryCount"],
"since": "2020-02-01T00:00:00Z",
"until": "2020-02-28T23:59:59Z",
"time_delta": "minute",
"limit": 2
}
},
"success": true,
"errors": [],
"messages": []
}

View File

@@ -0,0 +1,34 @@
{
"result": {
"rows": 1,
"data": [
{
"dimensions": ["thrdld.sld.tld", "TXT", "NOERROR"],
"metrics": [2]
}
],
"data_lag": 0,
"min": {},
"max": {},
"totals": {
"queryCount": 2
},
"query": {
"dimensions": ["queryName", "queryType", "responseCode"],
"metrics": ["queryCount"],
"filters": "responseCode==NOERROR AND queryType==TXT",
"sort": [
{
"Id": "queryCount",
"Desc": true
}
],
"since": "2020-02-01T00:00:00Z",
"until": "2020-02-28T23:59:59Z",
"limit": 10000
}
},
"success": true,
"errors": [],
"messages": []
}