bugfix: pagination, URL rewriting

pull/1/head
Adam Veldhousen 2021-06-10 16:57:29 -05:00
parent 79ff0c2cc1
commit e47893481a
Signed by: adam
GPG Key ID: 6DB29003C6DD1E4B
21 changed files with 292 additions and 2641 deletions

48
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,48 @@
name: Lint, Build, Deploy
on:
schedule:
- cron: '0 14 * * *'
push:
branches: [ trunk ]
pull_request:
branches: [ trunk ]
jobs:
gopherhole-verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest
# - name: Verify gopherhole
# run: |
# go get -u .
# make lint
client-verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Verify client
env:
NODE_ENV: production
run: |
cd ./client;
npm run verify
gopherhole-build:
runs-on: ubuntu-latest
needs: [client-verify, gopherhole-verify]
steps:
- uses: actions/checkout@v2
- name: Build gopherhole image
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: |
docker build \
--label="" \
-t vdhsn/gopherhole .

View File

@ -16,7 +16,7 @@ FROM golang:alpine as build-server
WORKDIR /build/
RUN apk add --no-cache --update make gcc musl-dev
RUN apk add --no-cache --update make gcc musl-dev git
COPY --from=build-client /build /build
RUN make .bin/gopherhole
@ -42,6 +42,4 @@ EXPOSE 53/udp 53/tcp 80/tcp
VOLUME "/data"
ENTRYPOINT /opt/gopherhole
CMD [ "-http-address=:80", "-dns-address=:53", "-upstream=${GOPHERHOLE_UPSTREAM}", "-db-path=/data"]
CMD /opt/gopherhole -http-address=0.0.0.0:80 -dns-address=0.0.0.0:53 -upstream ${GOPHERHOLE_UPSTREAM} -db-path /data

2505
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"scripts": {
"build": "NODE_ENV=production rollup -c",
"dev": "NODE_ENV=development rollup -c -w",
"start": "sirv public --single -G -D",
"start": "sirv public --single -G -D --host",
"validate": "svelte-check"
},
"devDependencies": {

View File

@ -33,6 +33,7 @@ export interface LogSearchOptions {
start: Date
end: Date
page: number
pageSize: number
filter: string
}
@ -40,12 +41,14 @@ export const getLogs = async({
start = sub(new Date(), { hours: 24 }),
end = new Date(),
page = 0,
pageSize = 25,
filter = ""
}: LogSearchOptions) => await apiCall<LogPayload>('metrics/log', 'GET', {
filter,
page,
start: getUnixTime(start),
end: getUnixTime(end),
start: getUnixTime(start || sub(new Date(), { hours: 24 })),
end: getUnixTime(end || new Date()),
pageSize
});
export interface StatsSearchOptions {
@ -84,8 +87,8 @@ export const getStats = async ({
key = StatSearchKey.Domain,
interval = 30,
}: StatsSearchOptions) => await apiCall<Stat>('metrics/stats', 'GET', {
start: getUnixTime(start),
end: getUnixTime(end),
start: getUnixTime(start || sub(new Date(), { hours: 24 })),
end: getUnixTime(end || new Date()),
key,
interval
});

View File

@ -29,9 +29,14 @@
export let defaultValue: Date = new Date();
export let value: Date = defaultValue;
$: dateTimeParts = toDateTimeParts(value);
$: dateTimeParts = toDateTimeParts(value || defaultValue || new Date());
const update = ({ target: { value: v } }) => {
if (!dateTimeParts) {
dateTimeParts = toDateTimeParts(defaultValue);
return;
}
const { date, time } = dateTimeParts;
let dateTimePartsInput = isDate(v)

View File

@ -6,18 +6,18 @@
PaginationLink,
} from "sveltestrap";
const pageSizes = [25, 50, 100, 250];
const pagerElementsCount = 10;
export let page: number = 0;
export let pages: number = 0;
export let total: number = 0;
export let pageSize: number = 50;
export let onPageChange = (newPage: number, prevPage: number) =>
console.log(`${newPage} - ${prevPage}`);
$: pageIndex = page + 1;
$: pageCount = pages === 0 ? 1 : pages;
$: pageSizeLabel = pageSize + "";
const pagerElementsCount = 10;
let pagesList = [];
$: {
pagesList = [];
@ -30,11 +30,14 @@
}
}
const handlePageSizeChange = ({ target: { value } }) => {
pageSize = Number(value);
};
const handlePageSizeChange = ({ target: { value } }) =>
(pageSize = Number(value));
const pageSizes = [25, 50, 100, 250];
const handlePageChange = (p) => (e) => {
e.preventDefault();
page = p;
console.debug(`changing to page ${page}`);
};
</script>
<section class="flex flex-row my-2 justify-between items-center">
@ -42,21 +45,35 @@
<div>
<Pagination size="sm">
<PaginationItem disabled={pageIndex === 1}>
<PaginationLink first href="#" />
<PaginationLink first href="#" on:click={handlePageChange(0)} />
</PaginationItem>
<PaginationItem disabled={pageIndex === 1}>
<PaginationLink previous href="#" />
<PaginationLink
previous
href="#"
on:click={handlePageChange(page - 1)}
/>
</PaginationItem>
{#each pagesList as p}
<PaginationItem active={pageIndex - 1 === p}>
<PaginationLink href="#">{p + 1}</PaginationLink>
<PaginationLink on:click={handlePageChange(p)} href="#"
>{p + 1}</PaginationLink
>
</PaginationItem>
{/each}
<PaginationItem disabled={pageIndex === pageCount}>
<PaginationLink next href="#" />
<PaginationLink
next
href="#"
on:click={handlePageChange(page + 1)}
/>
</PaginationItem>
<PaginationItem disabled={pageIndex === pageCount}>
<PaginationLink last href="#" />
<PaginationLink
last
href="#"
on:click={handlePageChange(pageCount)}
/>
</PaginationItem>
</Pagination>
</div>

View File

@ -8,16 +8,14 @@
export let pages: number = 0;
export let pageSize: number = 0;
export let total: number = 0;
export let onPageChange = (newPage: number, prevPage: number) =>
console.log(`${newPage} - ${prevPage}`);
$: pageSize = logs.length;
// $: pageSize = logs.length;
$: hasData = !!(logs && logs.length > 0);
</script>
<section class="flex flex-column text-sm">
{#if hasData}
<LogPager {onPageChange} {page} {pages} {pageSize} {total} />
<LogPager bind:page {pages} bind:pageSize {total} />
<Table rows={logs} let:row hover bordered>
<Column header="Started">
{row.Started}
@ -49,7 +47,7 @@
{row.TotalTimeMs}
</Column>
</Table>
<LogPager {onPageChange} {page} {pages} {pageSize} {total} />
<LogPager bind:page {pages} bind:pageSize {total} />
{:else}
<p>No Logs yet!</p>
<p>

View File

@ -50,12 +50,20 @@
</InputGroup>
</FormGroup>
<FormGroup class="flex flex-row">
<DatetimePicker
label="Start"
defaultValue={start}
bind:value={start}
/>
<DatetimePicker label="End" defaultValue={end} bind:value={end} />
<section class="px-1">
<DatetimePicker
label="Start"
defaultValue={start}
bind:value={start}
/>
</section>
<section class="px-1">
<DatetimePicker
label="End"
defaultValue={end}
bind:value={end}
/>
</section>
</FormGroup>
<FormGroup class="mx-2">
<Dropdown>

View File

@ -8,7 +8,7 @@
export let stats: Stat = null;
export let column: string = null;
const generateChartOptions = (s: Stat, empty: Boolean = false) => {
const generateChartOptions = (s: Stat = null, empty: Boolean = false) => {
let labels = [];
let datasets = [];

View File

@ -16,28 +16,28 @@
const { search } = location;
let params = new URLSearchParams(search.substring(1));
export let start: Date =
fromUnixTimeSafe(params.get("start")) || sub(new Date(), { hours: 24 });
export let end: Date = fromUnixTimeSafe(params.get("end")) || new Date();
export let filter: string = params.get("filter") || "";
const aggKey = params.get("key");
const fixed = aggKey[0].toUpperCase() + aggKey.substr(1);
const fixed = aggKey
? aggKey[0].toUpperCase() + aggKey.substr(1)
: "Domain";
export let chartKey: StatSearchKey =
StatSearchKey[fixed] || StatSearchKey.Domain;
export let chartInterval: number = 30;
export let logPage: number = 0;
let start: Date = fromUnixTimeSafe(params.get("start")) || null;
let end: Date = fromUnixTimeSafe(params.get("end")) || null;
let logErrorMsg: string = null;
let chartErrorMsg: string = null;
let chartDataLoading: Boolean = false;
let logDataLoading: Boolean = false;
let filter: string = params.get("filter") || "";
let chartKey: StatSearchKey = StatSearchKey[fixed] || StatSearchKey.Domain;
let chartInterval: number = 30;
let page: number = Number(params.get("page") || 0);
let chartData: Stat = null;
let chartErrorMsg: string = null;
let chartDataLoading: Boolean = false;
let logs: Log[] = [];
let pageSize: number = 50;
let logErrorMsg: string = null;
let logDataLoading: Boolean = false;
let pageSize: number = Number(params.get("pageSize") || 25);
let pageCount: number = 0;
let logCount: number = 0;
@ -52,7 +52,8 @@
const { error, payload } = await getLogs({
start,
end,
page: logPage,
page,
pageSize,
filter,
});
logDataLoading = false;
@ -89,43 +90,56 @@
return payload;
};
let done = true;
const updateData = async (evt) => {
if (chartDataLoading || logDataLoading) {
console.warn("SKIPPED DATA FETCH");
if (chartDataLoading || logDataLoading || !done) {
console.debug("SKIPPED DATA FETCH");
return;
}
console.groupCollapsed("Stats Data Update");
const { filter: eFilter, start: eStart, end: eEnd, key: eKey } = evt;
console.info("handled search, fetching new data:", evt);
const {
filter: eFilter,
start: eStart,
end: eEnd,
key: eKey,
page: ePage,
pageSize: eps,
} = evt;
console.debug("handled search, fetching new data:", evt);
console.groupEnd();
let truePage =
logCount <= pageSize * page ? 0 : ePage === 0 ? null : ePage;
if (logCount <= pageSize * page) {
console.warn(
"adjusting log page because logCount is too small for current settings"
);
page = 0;
}
navigate(
`${location?.pathname}${buildQueryParams({
start: getUnixTime(eStart),
end: getUnixTime(eEnd),
filter: eFilter,
key: eKey,
start: eStart ? getUnixTime(eStart) : null,
end: eEnd ? getUnixTime(eEnd) : null,
filter: eFilter === "" ? eFilter : null,
key: eKey !== "domain" ? eKey : null,
page: truePage,
pageSize: eps && eps !== 25 ? eps : null,
})}`,
{ replace: true }
);
const [logPayload, chartPayload] = await Promise.all([
fetchLogs(),
fetchStats(),
]);
chartData = chartPayload;
[{ page, total: logCount, pageCount, pageSize, logs }, chartData] =
await Promise.all([fetchLogs(), fetchStats()]);
({
page: logPage,
total: logCount,
pageCount,
pageSize,
logs,
} = logPayload);
done = true;
};
$: updateData({ start, end, key: chartKey, filter });
// $: updateChart({ start, end, key: chartKey });
// $: updateLog({ start, end, page, pageSize });
$: updateData({ start, end, key: chartKey, filter, pageSize, page });
</script>
<PageContainer
@ -151,11 +165,10 @@
{:else}
<LogViewer
pages={pageCount}
page={logPage}
total={logCount}
{pageSize}
onPageChange={console.log}
{logs}
bind:page
bind:pageSize
/>
{/if}
</section>

View File

@ -1,10 +1,6 @@
package main
import (
"encoding/json"
"fmt"
"os"
"github.com/adamveld12/gopherhole/internal"
)
@ -16,16 +12,3 @@ type StartupConfig struct {
Recursors []string `json:"recursors"`
Rules []internal.Rule `json:"rules"`
}
func LoadStartupConfig(conf *StartupConfig, file string) error {
data, err := os.Open(file)
if err != nil {
return fmt.Errorf("could not open file: %w", err)
}
if err := json.NewDecoder(data).Decode(conf); err != nil {
return fmt.Errorf("could not read json file: %w", err)
}
return nil
}

1
go.mod
View File

@ -9,5 +9,4 @@ require (
github.com/gorilla/websocket v1.4.2
github.com/mattn/go-sqlite3 v1.14.7
github.com/miekg/dns v1.1.41
github.com/nakabonne/tstorage v0.1.2 // indirect
)

9
go.sum
View File

@ -1,4 +1,3 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg=
github.com/go-chi/chi/v5 v5.0.2 h1:4xKeALZdMEsuI5s05PU2Bm89Uc5iM04qFubUCl5LfAQ=
@ -11,13 +10,9 @@ github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEg
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/nakabonne/tstorage v0.1.2 h1:kZcXXyO10DDUvDBRHhRo9+VwSTAuvIGt/WpEb+TXAbM=
github.com/nakabonne/tstorage v0.1.2/go.mod h1:n1v68nvIeUguEaYuSqz1ycmiMkF02CJMKSJV0Of1h4w=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g=
@ -25,5 +20,3 @@ golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -99,6 +99,12 @@ func GetAggregateColumnHeader(ql QueryLog, h LogAggregateColumn) string {
return string(ql.Status)
case Protocol:
return ql.Protocol
case Domain:
return ql.Domain
case RecurseIP:
return ql.RecurseUpstreamIP
case LookupError:
return ql.Error
}
return ql.Domain

View File

@ -53,7 +53,6 @@ func (a *adminHandler) getStats(r *http.Request) (*RestResponse, error) {
}
return BasicResponse(true, la), nil
}
type LogFilter struct {
@ -64,11 +63,13 @@ func (a *adminHandler) getLog(r *http.Request) (*RestResponse, error) {
q := r.URL.Query()
startFilter := q.Get("start")
endFilter := q.Get("end")
pageSizeStr := q.Get("pageSize")
// filter := LogFilter{Expression: q.Get("filter")}
pageStr := q.Get("page")
var err error
var page int
pageSize := 25
startTime := time.Now().Add(time.Hour * -86400)
endTime := time.Now()
@ -96,11 +97,17 @@ func (a *adminHandler) getLog(r *http.Request) (*RestResponse, error) {
}
}
if pageSizeStr != "" {
if pageSize, err = strconv.Atoi(pageSizeStr); err != nil {
return BasicResponse(false, "pageSize: must be a valid integer"), nil
}
}
gli := GetLogInput{
// Filter: filter,
Start: startTime,
End: endTime,
Limit: 250,
Limit: pageSize,
Page: page,
}

View File

@ -21,7 +21,7 @@ type Resolved struct {
func (r Recursor) Resolve(request *dns.Msg) (Resolved, error) {
var result Resolved
errs := make([]error, len(r.Upstreams))
errs := make([]error, 0, len(r.Upstreams))
var err error
var upstreamsTried int

View File

@ -50,6 +50,8 @@ func getType(rt RuleType) uint16 {
return dns.TypeA
case CNAME:
return dns.TypeCNAME
case Recurse:
break
}
return 0

View File

@ -13,6 +13,11 @@ import (
_ "github.com/mattn/go-sqlite3"
)
const (
defaultSamples = 64
maxSamples = 128
)
type Sqlite struct {
Path string
*sql.DB
@ -40,9 +45,6 @@ func (ss *Sqlite) Close() error {
return nil
}
const defaultSamples = 64
const maxSamples = 128
func (ss *Sqlite) GetLogAggregate(la LogAggregateInput) (LogAggregate, error) {
if la.End.IsZero() || la.End.After(time.Now()) {
la.End = time.Now().UTC()
@ -71,7 +73,6 @@ func (ss *Sqlite) GetLogAggregate(la LogAggregateInput) (LogAggregate, error) {
if sampleCount > maxSamples {
sampleCount = maxSamples
la.IntervalSeconds = timespanSecs / sampleCount
log.Printf("got %v samples, capping to 256 for perf", sampleCount)
}
log.Printf("%+v - samples: %v - timespan (seconds): %v", la, sampleCount, timespanSecs)
@ -189,9 +190,12 @@ func (ss *Sqlite) GetRecursors() ([]RecursorRow, error) {
if err != nil {
return nil, fmt.Errorf("could not execute select for recursors: %w", err)
}
defer rows.Close()
if err := rows.Err(); err != nil {
return nil, err
}
results := []RecursorRow{}
for rows.Next() {
var row RecursorRow
@ -355,7 +359,7 @@ func (ss *Sqlite) GetRules() ([]RuleRow, error) {
func (ss *Sqlite) GetLog(in GetLogInput) (GetLogResult, error) {
if in.Limit <= 0 {
in.Limit = 100
in.Limit = 25
}
if in.Start.IsZero() {
@ -371,21 +375,37 @@ func (ss *Sqlite) GetLog(in GetLogInput) (GetLogResult, error) {
Logs: []QueryLog{},
}
lpi, err := ss.GetPagingInfo(in)
if err != nil {
return glr, err
}
glr.TotalResults = lpi.Total
glr.PageCount = lpi.PageCount + 1
sql := `
SELECT
started, clientIp, protocol, domain, totalTimeMs,
error, recurseRoundTripTimeMs, recurseUpstreamIp, status
FROM
log
WHERE
id > ?
AND strftime('%s', started) > strftime('%s', ?)
AND strftime('%s', started) < strftime('%s', ?)
ORDER BY started DESC
LIMIT ?;
started, clientIp, protocol, domain, totalTimeMs,
error, recurseRoundTripTimeMs, recurseUpstreamIp, status
FROM (
SELECT id,
started,
clientIp,
protocol,
domain,
totalTimeMs,
error,
recurseRoundTripTimeMs,
recurseUpstreamIp,
status
FROM log
WHERE strftime('%s', started) >= strftime('%s', ?)
AND strftime('%s', started) <= strftime('%s', ?)
ORDER BY started DESC
) WHERE id <= ? ORDER BY id DESC LIMIT ?;
`
rows, err := ss.DB.Query(sql, in.Page*in.Limit, in.Start.UTC().Format(ISO8601), in.End.UTC().Format(ISO8601), in.Limit)
rows, err := ss.DB.Query(sql, in.Start.UTC().Format(ISO8601), in.End.UTC().Format(ISO8601), lpi.FirstItemID, in.Limit)
if err != nil {
return glr, fmt.Errorf("issue with GetLog sql query: %w", err)
}
@ -420,34 +440,39 @@ func (ss *Sqlite) GetLog(in GetLogInput) (GetLogResult, error) {
glr.Logs = append(glr.Logs, q)
}
total, pageCount, err := ss.GetPagingInfo(in)
if err != nil {
return glr, err
}
glr.TotalResults = total
glr.PageCount = pageCount
return glr, nil
}
func (ss *Sqlite) GetPagingInfo(in GetLogInput) (totalItems, pageCount int, err error) {
type LogPageInfo struct {
Total int
PageCount int
FirstItemID int
}
func (ss *Sqlite) GetPagingInfo(in GetLogInput) (lpi LogPageInfo, err error) {
sql := `
SELECT
COUNT(*) as totalLogsEntries,
COUNT(*) / ? as pageCount
COUNT(*) / ? as pageCount,
MAX(id) - ? as firstItemId
FROM
log
WHERE
strftime('%s', started) > strftime('%s', ?)
strftime('%s', started) > strftime('%s', ?)
AND strftime('%s', started) < strftime('%s', ?)
ORDER BY id DESC
`
row := ss.QueryRow(sql, in.Limit, in.Start.UTC().Format(ISO8601), in.End.UTC().Format(ISO8601))
if err = row.Scan(&totalItems, &pageCount); err != nil {
pageOffset := in.Limit * in.Page
row := ss.QueryRow(sql, in.Limit, pageOffset, in.Start.UTC().Format(ISO8601), in.End.UTC().Format(ISO8601))
if err = row.Scan(&lpi.Total, &lpi.PageCount, &lpi.FirstItemID); err != nil {
return
}
if pageOffset > lpi.Total {
err = errors.New("page number too high")
}
return
}

View File

@ -14,8 +14,8 @@ import (
var (
dbPath = flag.String("db-path", ".", "Directory to write database files to")
httpAddr = flag.String("http-address", ":80", "Bind address for http server")
dnsAddr = flag.String("dns-address", ":53", "Bind address for dns server")
httpAddr = flag.String("http-address", "0.0.0.0:80", "Bind address for http server")
dnsAddr = flag.String("dns-address", "0.0.0.0:53", "Bind address for dns server")
defaultUpstream = flag.String("upstream", "1.1.1.1:53", "default upstream DNS server when no others are specified")
)

View File

@ -1,8 +1,21 @@
LINTBIN := $(shell go env GOPATH)/bin/golangci-lint
COMMIT_SHA := $(shell git rev-parse HEAD | cut -c 1-11)
build: clobber .bin/client/public .bin/gopherhole
dev: clean .bin/gopherhole
cd .bin && ./gopherhole -dns-address=:5353 -http-address=:8000
client-dev:
docker run -it --rm --name='client-dev' \
--workdir /opt/client \
-v $$PWD/client:/opt/client \
--entrypoint ash \
--user $${UID}:$${GID} \
--memory=4g \
-p 5000:5000 \
node:lts-alpine
clean:
@rm -rf .bin/gopherhole .bin/client
@ -10,7 +23,14 @@ clobber: clean
@rm -rf .bin ./client/node_modules ./client/public/build
vdhsn/gopherhole:
docker build -t vdhsn/gopherhole:latest .
docker build \
--label="org.opencontainers.image.created=$(shell date +'%FT%T%:z')" \
--label="org.opencontainers.image.source=https://github.com/adamveld12/gopherhole.git" \
--label="org.opencontainers.image.url=https://github.com/adamveld12/gopherhole" \
--label="org.opencontainers.image.revision=$(COMMIT_SHA)" \
--label="org.opencontainers.image.licenses=MIT" \
--label="org.opencontainers.image.authors=Adam Veldhousen <adam@vdhsn.com>" \
-t vdhsn/gopherhole:latest .
test:
dig -p 5353 twitter.com @localhost
@ -18,8 +38,26 @@ test:
dig -p 5353 loki.veldhousen.ninja @localhost
dig -p 5353 www.liveauctioneers.com @localhost
lint: tidy
# lint: $(LINTBIN) tidy
# golangci-lint run -p bugs \
# -p performance \
# -p unused \
# -p complexity \
# --sort-results \
# --max-same-issues 5 \
# --no-config \
# --verbose \
# --timeout 30s \
# --concurrency 4 \
# --issues-exit-code 1
tidy:
go mod tidy
.PHONY: build clean clobber client-dev dev lint tidy test vdhsn/gopherhole
.PHONY: build clean clobber client-dev dev test vdhsn/gopherhole
.bin:
mkdir -p .bin
@ -27,9 +65,6 @@ test:
.bin/gopherhole: .bin
@go build --tags "fts5" -v -o .bin/gopherhole .
client-dev: client/node_modules
cd ./client && npm run dev
.bin/client/public: .bin client/public/build
mkdir -p .bin/client/public
cp -R ./client/public/ .bin/client/
@ -39,3 +74,9 @@ client/public/build: client/node_modules
client/node_modules:
cd ./client && npm install
$(LINTBIN):
echo "installing golangci-lint to $(LINTBIN)..."
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin latest
chmod +x $(LINTBIN)