Skip to content

Commit e0d255b

Browse files
Cache configuration (lucasdillmann#61)
1 parent e363fa5 commit e0d255b

372 files changed

Lines changed: 4434 additions & 1711 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.golangci.yml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ linters:
3030
min-len: 3
3131
min-occurrences: 3
3232
gocyclo:
33-
min-complexity: 15
33+
min-complexity: 20
3434
gosec:
3535
excludes:
3636
- G204
@@ -114,15 +114,6 @@ linters:
114114
- gocyclo
115115
- gosec
116116
path: _test\.go
117-
- linters:
118-
- gosec
119-
text: 'G304: Potential file inclusion via variable'
120-
- path: (.+)\.go$
121-
text: Error return value of `.*` is not checked
122-
- path: (.+)\.go$
123-
text: func name will be used as test\.Test.* by other packages, and that stutters; consider calling this
124-
- path: (.+)\.go$
125-
text: (comment on exported (method|function|type|const)|should have( a package)? comment|comment should be of the form)
126117
paths:
127118
- vendor
128119
- testdata

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ENV NGINX_IGNITION_NGINX_BINARY_PATH="/usr/sbin/nginx" \
2424
NGINX_IGNITION_DATABASE_DRIVER="sqlite" \
2525
NGINX_IGNITION_DATABASE_MIGRATIONS_PATH="/opt/nginx-ignition/migrations" \
2626
NGINX_IGNITION_DATABASE_DATA_PATH="/opt/nginx-ignition/data" \
27-
GOMEMLIMIT="96MiB"
27+
GOMEMLIMIT="128MiB"
2828

2929
ENTRYPOINT ["/opt/nginx-ignition/nginx-ignition"]
3030
WORKDIR /opt/nginx-ignition

Makefile

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ LDFLAGS := -X 'dillmann.com.br/nginx-ignition/core/common/version.Number=$(VERSI
1313

1414
.backend-check:
1515
go tool golangci-lint run \
16-
./api \
17-
./application \
18-
./certificate/commons \
19-
./certificate/custom \
20-
./certificate/letsencrypt \
21-
./certificate/selfsigned \
22-
./core \
23-
./database \
24-
./integration/docker \
25-
./integration/truenas \
26-
./vpn/tailscale
16+
./api/... \
17+
./application/... \
18+
./certificate/commons/... \
19+
./certificate/custom/... \
20+
./certificate/letsencrypt/... \
21+
./certificate/selfsigned/... \
22+
./core/... \
23+
./database/... \
24+
./integration/docker/... \
25+
./integration/truenas/... \
26+
./vpn/tailscale/...
2727

2828
.build-frontend:
2929
cd frontend/ && npm run build
@@ -81,8 +81,20 @@ LDFLAGS := -X 'dillmann.com.br/nginx-ignition/core/common/version.Number=$(VERSI
8181
check: .prerequisites .frontend-check .backend-check
8282

8383
format: .prerequisites
84-
go tool gofumpt -w .
8584
cd frontend/ && npx prettier --write .
85+
go tool gofumpt -w .
86+
go tool fieldalignment -fix \
87+
./api/... \
88+
./application/... \
89+
./certificate/commons/... \
90+
./certificate/custom/... \
91+
./certificate/letsencrypt/... \
92+
./certificate/selfsigned/... \
93+
./core/... \
94+
./database/... \
95+
./integration/docker/... \
96+
./integration/truenas/... \
97+
./vpn/tailscale/...
8698

8799
update-dependencies:
88100
cd api && go get -u all

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Some of the available features include:
2727
- Native integration with Docker and Docker Swarm for easy pick of a container/service as the proxy target
2828
- Built-in support for Tailscale VPNs, enabling easy exposure of hosts in your Tailnet networks as virtual machines
2929
- Access lists for easy control of who can access what using basic authentication and/or source IP address checks
30+
- Easy nginx content caching configuration
3031

3132
## Getting started
3233

api/accesslist/converter.go

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ func toDto(accessList *accesslist.AccessList) *accessListResponseDto {
1111
return nil
1212
}
1313

14-
var entries []entrySetDto
14+
entries := make([]entrySetDto, 0)
1515
for _, entry := range accessList.Entries {
1616
entries = append(entries, entrySetDto{
1717
Priority: &entry.Priority,
@@ -20,7 +20,7 @@ func toDto(accessList *accesslist.AccessList) *accessListResponseDto {
2020
})
2121
}
2222

23-
var credentials []credentialsDto
23+
credentials := make([]credentialsDto, 0)
2424
for _, credential := range accessList.Credentials {
2525
credentials = append(credentials, credentialsDto{
2626
Username: &credential.Username,
@@ -45,25 +45,21 @@ func toDomain(request *accessListRequestDto) *accesslist.AccessList {
4545
return nil
4646
}
4747

48-
var entries []accesslist.AccessListEntry
49-
if request.Entries != nil {
50-
for _, entry := range request.Entries {
51-
entries = append(entries, accesslist.AccessListEntry{
52-
Priority: *entry.Priority,
53-
Outcome: *entry.Outcome,
54-
SourceAddress: entry.SourceAddresses,
55-
})
56-
}
48+
entries := make([]accesslist.Entry, 0)
49+
for _, entry := range request.Entries {
50+
entries = append(entries, accesslist.Entry{
51+
Priority: *entry.Priority,
52+
Outcome: *entry.Outcome,
53+
SourceAddress: entry.SourceAddresses,
54+
})
5755
}
5856

59-
var credentials []accesslist.AccessListCredentials
60-
if request.Credentials != nil {
61-
for _, credential := range request.Credentials {
62-
credentials = append(credentials, accesslist.AccessListCredentials{
63-
Username: *credential.Username,
64-
Password: *credential.Password,
65-
})
66-
}
57+
credentials := make([]accesslist.Credentials, 0)
58+
for _, credential := range request.Credentials {
59+
credentials = append(credentials, accesslist.Credentials{
60+
Username: *credential.Username,
61+
Password: *credential.Password,
62+
})
6763
}
6864

6965
return &accesslist.AccessList{

api/accesslist/dto.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@ type accessListRequestDto struct {
1111
Realm *string `json:"realm"`
1212
SatisfyAll *bool `json:"satisfyAll"`
1313
DefaultOutcome *accesslist.Outcome `json:"defaultOutcome"`
14-
Entries []*entrySetDto `json:"entries"`
14+
Entries []entrySetDto `json:"entries"`
1515
ForwardAuthenticationHeader *bool `json:"forwardAuthenticationHeader"`
16-
Credentials []*credentialsDto `json:"credentials"`
16+
Credentials []credentialsDto `json:"credentials"`
1717
}
1818

1919
type accessListResponseDto struct {
20-
ID uuid.UUID `json:"id"`
21-
Name string `json:"name"`
2220
Realm *string `json:"realm"`
23-
SatisfyAll bool `json:"satisfyAll"`
21+
Name string `json:"name"`
2422
DefaultOutcome accesslist.Outcome `json:"defaultOutcome"`
2523
Entries []entrySetDto `json:"entries"`
26-
ForwardAuthenticationHeader bool `json:"forwardAuthenticationHeader"`
2724
Credentials []credentialsDto `json:"credentials"`
25+
ID uuid.UUID `json:"id"`
26+
SatisfyAll bool `json:"satisfyAll"`
27+
ForwardAuthenticationHeader bool `json:"forwardAuthenticationHeader"`
2828
}
2929

3030
type entrySetDto struct {
3131
Priority *int `json:"priority"`
3232
Outcome *accesslist.Outcome `json:"outcome"`
33-
SourceAddresses []*string `json:"sourceAddresses"`
33+
SourceAddresses []string `json:"sourceAddresses"`
3434
}
3535

3636
type credentialsDto struct {

api/cache/converter.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package cache
2+
3+
import (
4+
"github.com/google/uuid"
5+
6+
"dillmann.com.br/nginx-ignition/core/cache"
7+
)
8+
9+
func toDomain(id uuid.UUID, dto *cacheRequestDto) *cache.Cache {
10+
durations := make([]cache.Duration, len(dto.Durations))
11+
for index, duration := range dto.Durations {
12+
durations[index] = cache.Duration{
13+
StatusCodes: duration.StatusCodes,
14+
ValidTimeSeconds: duration.ValidTimeSeconds,
15+
}
16+
}
17+
18+
return &cache.Cache{
19+
ID: id,
20+
Name: dto.Name,
21+
StoragePath: dto.StoragePath,
22+
InactiveSeconds: dto.InactiveSeconds,
23+
MaximumSizeMB: dto.MaximumSizeMB,
24+
AllowedMethods: dto.AllowedMethods,
25+
MinimumUsesBeforeCaching: dto.MinimumUsesBeforeCaching,
26+
UseStale: dto.UseStale,
27+
BackgroundUpdate: dto.BackgroundUpdate,
28+
Revalidate: dto.Revalidate,
29+
BypassRules: dto.BypassRules,
30+
NoCacheRules: dto.NoCacheRules,
31+
FileExtensions: dto.FileExtensions,
32+
IgnoreUpstreamCacheHeaders: dto.IgnoreUpstreamCacheHeaders,
33+
CacheStatusResponseHeaderEnabled: dto.CacheStatusResponseHeaderEnabled,
34+
Durations: durations,
35+
ConcurrencyLock: cache.ConcurrencyLock{
36+
Enabled: dto.ConcurrencyLock.Enabled,
37+
TimeoutSeconds: dto.ConcurrencyLock.TimeoutSeconds,
38+
AgeSeconds: dto.ConcurrencyLock.AgeSeconds,
39+
},
40+
}
41+
}
42+
43+
func toResponseDto(domain *cache.Cache) cacheResponseDto {
44+
durations := make([]durationDto, len(domain.Durations))
45+
for index, duration := range domain.Durations {
46+
durations[index] = durationDto{
47+
StatusCodes: duration.StatusCodes,
48+
ValidTimeSeconds: duration.ValidTimeSeconds,
49+
}
50+
}
51+
52+
return cacheResponseDto{
53+
ID: domain.ID,
54+
Name: domain.Name,
55+
StoragePath: domain.StoragePath,
56+
InactiveSeconds: domain.InactiveSeconds,
57+
MaximumSizeMB: domain.MaximumSizeMB,
58+
AllowedMethods: domain.AllowedMethods,
59+
MinimumUsesBeforeCaching: domain.MinimumUsesBeforeCaching,
60+
UseStale: domain.UseStale,
61+
BackgroundUpdate: domain.BackgroundUpdate,
62+
Revalidate: domain.Revalidate,
63+
BypassRules: domain.BypassRules,
64+
NoCacheRules: domain.NoCacheRules,
65+
FileExtensions: domain.FileExtensions,
66+
IgnoreUpstreamCacheHeaders: domain.IgnoreUpstreamCacheHeaders,
67+
CacheStatusResponseHeaderEnabled: domain.CacheStatusResponseHeaderEnabled,
68+
Durations: durations,
69+
ConcurrencyLock: concurrencyLockDto{
70+
Enabled: domain.ConcurrencyLock.Enabled,
71+
TimeoutSeconds: domain.ConcurrencyLock.TimeoutSeconds,
72+
AgeSeconds: domain.ConcurrencyLock.AgeSeconds,
73+
},
74+
}
75+
}

api/cache/create_handler.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package cache
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/gin-gonic/gin"
7+
"github.com/google/uuid"
8+
9+
"dillmann.com.br/nginx-ignition/api/common/converter"
10+
"dillmann.com.br/nginx-ignition/core/cache"
11+
)
12+
13+
type createHandler struct {
14+
commands *cache.Commands
15+
}
16+
17+
func (h createHandler) handle(ctx *gin.Context) {
18+
var dto cacheRequestDto
19+
if err := ctx.BindJSON(&dto); err != nil {
20+
panic(err)
21+
}
22+
23+
id := uuid.New()
24+
domain := converter.Wrap2(toDomain, id, &dto)
25+
if err := h.commands.Save(ctx.Request.Context(), domain); err != nil {
26+
panic(err)
27+
}
28+
29+
ctx.JSON(http.StatusCreated, toResponseDto(domain))
30+
}

api/cache/delete_handler.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cache
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/gin-gonic/gin"
7+
"github.com/google/uuid"
8+
9+
"dillmann.com.br/nginx-ignition/core/cache"
10+
)
11+
12+
type deleteHandler struct {
13+
commands *cache.Commands
14+
}
15+
16+
func (h deleteHandler) handle(ctx *gin.Context) {
17+
id, err := uuid.Parse(ctx.Param("id"))
18+
if err != nil {
19+
ctx.Status(http.StatusNotFound)
20+
return
21+
}
22+
23+
if err := h.commands.Delete(ctx.Request.Context(), id); err != nil {
24+
panic(err)
25+
}
26+
27+
ctx.Status(http.StatusNoContent)
28+
}

api/cache/dto.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package cache
2+
3+
import (
4+
"github.com/google/uuid"
5+
6+
"dillmann.com.br/nginx-ignition/core/cache"
7+
)
8+
9+
type cacheRequestDto struct {
10+
StoragePath *string `json:"storagePath"`
11+
InactiveSeconds *int `json:"inactiveSeconds"`
12+
MaximumSizeMB *int `json:"maximumSizeMb"`
13+
ConcurrencyLock concurrencyLockDto `json:"concurrencyLock"`
14+
Name string `json:"name"`
15+
UseStale []cache.UseStaleOption `json:"useStale"`
16+
AllowedMethods []cache.Method `json:"allowedMethods"`
17+
BypassRules []string `json:"bypassRules"`
18+
NoCacheRules []string `json:"noCacheRules"`
19+
FileExtensions []string `json:"fileExtensions"`
20+
Durations []durationDto `json:"durations"`
21+
MinimumUsesBeforeCaching int `json:"minimumUsesBeforeCaching"`
22+
BackgroundUpdate bool `json:"backgroundUpdate"`
23+
Revalidate bool `json:"revalidate"`
24+
IgnoreUpstreamCacheHeaders bool `json:"ignoreUpstreamCacheHeaders"`
25+
CacheStatusResponseHeaderEnabled bool `json:"cacheStatusResponseHeaderEnabled"`
26+
}
27+
28+
type cacheResponseDto struct {
29+
InactiveSeconds *int `json:"inactiveSeconds"`
30+
StoragePath *string `json:"storagePath"`
31+
MaximumSizeMB *int `json:"maximumSizeMb"`
32+
ConcurrencyLock concurrencyLockDto `json:"concurrencyLock"`
33+
Name string `json:"name"`
34+
UseStale []cache.UseStaleOption `json:"useStale"`
35+
AllowedMethods []cache.Method `json:"allowedMethods"`
36+
BypassRules []string `json:"bypassRules"`
37+
NoCacheRules []string `json:"noCacheRules"`
38+
FileExtensions []string `json:"fileExtensions"`
39+
Durations []durationDto `json:"durations"`
40+
MinimumUsesBeforeCaching int `json:"minimumUsesBeforeCaching"`
41+
ID uuid.UUID `json:"id"`
42+
Revalidate bool `json:"revalidate"`
43+
BackgroundUpdate bool `json:"backgroundUpdate"`
44+
IgnoreUpstreamCacheHeaders bool `json:"ignoreUpstreamCacheHeaders"`
45+
CacheStatusResponseHeaderEnabled bool `json:"cacheStatusResponseHeaderEnabled"`
46+
}
47+
48+
type concurrencyLockDto struct {
49+
TimeoutSeconds *int `json:"timeoutSeconds"`
50+
AgeSeconds *int `json:"ageSeconds"`
51+
Enabled bool `json:"enabled"`
52+
}
53+
54+
type durationDto struct {
55+
StatusCodes []string `json:"statusCodes"`
56+
ValidTimeSeconds int `json:"validTimeSeconds"`
57+
}

0 commit comments

Comments
 (0)