diff --git a/public/i18n/en/settings.json b/public/i18n/en/settings.json index aef67ae..c0dd2c9 100644 --- a/public/i18n/en/settings.json +++ b/public/i18n/en/settings.json @@ -28,5 +28,8 @@ "Detected custom upstream server": "Detected custom upstream server", "DNS Options": "DNS Options", "Rapid Commit": "Rapid Commit", - "Prefix length (CIDR)": "Prefix length (CIDR)" + "Prefix length (CIDR)": "Prefix length (CIDR)", + "DNS cache size": "DNS cache size", + "DNS cache evictions": "DNS cache evictions", + "DNS cache insertions": "DNS cache insertions" } \ No newline at end of file diff --git a/scripts/make-fake-data.js b/scripts/make-fake-data.js index 10ebf1b..203b2d8 100644 --- a/scripts/make-fake-data.js +++ b/scripts/make-fake-data.js @@ -384,6 +384,14 @@ function getPreferences() { }; } +function cacheinfo() { + return { + cache_size: faker.random.number(), + cache_evicted: faker.random.number(), + cache_inserted: faker.random.number() + }; +} + function getDnsmasqLog() { return { log: [ @@ -408,6 +416,7 @@ write("public/fakeAPI/dns/whitelist", list()); write("public/fakeAPI/dns/blacklist", list()); write("public/fakeAPI/dns/regexlist", list()); write("public/fakeAPI/dns/status", status()); +write("public/fakeAPI/dns/cacheinfo", cacheinfo()); write("public/fakeAPI/settings/dhcp", getDHCPInfo()); write("public/fakeAPI/settings/dns", getDNSInfo()); write("public/fakeAPI/settings/network", getNetworkInfo()); diff --git a/src/components/settings/CacheInfo.tsx b/src/components/settings/CacheInfo.tsx new file mode 100644 index 0000000..44c9015 --- /dev/null +++ b/src/components/settings/CacheInfo.tsx @@ -0,0 +1,108 @@ +/* Pi-hole: A black hole for Internet advertisements + * (c) 2019 Pi-hole, LLC (https://pi-hole.net) + * Network-wide ad blocking via your own hardware. + * + * Web Interface + * Settings :: DNS Cache Information component + * + * This file is copyright under the latest version of the EUPL. + * Please see LICENSE file for your rights under this license. */ + +import React, { Component } from "react"; +import { WithTranslation, withTranslation } from "react-i18next"; +import { Form, Col, Input, FormGroup, Label } from "reactstrap"; +import api from "../../util/api"; +import { + CancelablePromise, + ignoreCancel, + makeCancelable +} from "../../util/CancelablePromise"; + +export interface CacheInfoState { + cache_size: number; + cache_evicted: number; + cache_inserted: number; +} + +class CacheInfo extends Component { + state: CacheInfoState = { + cache_size: 0, + cache_evicted: 0, + cache_inserted: 0 + }; + + componentDidMount() { + this.loadCacheInfo(); + } + + componentWillUnmount() { + if (this.loadHandler) { + this.loadHandler.cancel(); + } + } + + private loadHandler: undefined | CancelablePromise; + + loadCacheInfo = () => { + this.loadHandler = makeCancelable(api.getCacheInfo()); + this.loadHandler.promise + .then(res => { + this.setState({ + cache_size: res.cache_size, + cache_evicted: res.cache_evicted, + cache_inserted: res.cache_inserted + }); + }) + .catch(ignoreCancel); + }; + + render() { + const { t } = this.props; + + return ( +
+ + + + + + + + + + + + + + + + + + +
+ ); + } +} + +export default withTranslation(["settings"])(CacheInfo); diff --git a/src/types/api.d.ts b/src/types/api.d.ts index ecc14b7..0b1615a 100644 --- a/src/types/api.d.ts +++ b/src/types/api.d.ts @@ -76,6 +76,12 @@ interface ApiFtlDbResponse { sqlite_version: string; } +interface ApiCacheResponse { + cache_size: number; + cache_evicted: number; + cache_inserted: number; +} + interface ApiSuccessResponse { status: "success"; } diff --git a/src/util/__tests__/api.test.tsx b/src/util/__tests__/api.test.tsx index a063c75..c793c64 100644 --- a/src/util/__tests__/api.test.tsx +++ b/src/util/__tests__/api.test.tsx @@ -394,6 +394,11 @@ describe("ApiClient", () => { await expect(api.updatePreferences(settings)).resolves.toEqual(putData); expect(httpClient.put).toHaveBeenCalledWith("settings/web", settings); }); + + it("should call get dns cache endpoint", async () => { + await expect(api.getCacheInfo()).resolves.toEqual(getData); + expect(httpClient.get).toHaveBeenCalledWith("dns/cacheinfo"); + }); }); describe("utility calls", () => { diff --git a/src/util/api.tsx b/src/util/api.tsx index 9909ec8..4b663e4 100644 --- a/src/util/api.tsx +++ b/src/util/api.tsx @@ -239,6 +239,10 @@ export class ApiClient { return this.http.get("settings/ftldb"); }; + getCacheInfo = (): Promise => { + return this.http.get("dns/cacheinfo"); + }; + getDNSInfo = (): Promise => { return this.http.get("settings/dns"); }; diff --git a/src/views/Networking.tsx b/src/views/Networking.tsx index 33a0b1d..449606a 100644 --- a/src/views/Networking.tsx +++ b/src/views/Networking.tsx @@ -13,6 +13,7 @@ import { WithTranslation, withTranslation } from "react-i18next"; import { Nav, NavItem, NavLink, TabContent, TabPane } from "reactstrap"; import DHCPInfo from "../components/settings/DHCPInfo"; import DNSInfo from "../components/settings/DNSInfo"; +import CacheInfo from "../components/settings/CacheInfo"; import NetworkInfo from "../components/settings/NetworkInfo"; import FTLInfo from "../components/settings/FTLInfo"; @@ -77,12 +78,14 @@ class Networking extends Component { {this.tab("dhcp", t("DHCP"))} {this.tab("dns", t("DNS"))} {this.tab("ftl", t("FTL"))} + {this.tab("cache", t("Cache"))} {this.tabContent("network", )} {this.tabContent("dhcp", )} {this.tabContent("dns", )} {this.tabContent("ftl", )} + {this.tabContent("cache", )} );