Skip to content

Commit

Permalink
Merge pull request #1 from saturncloud/bhperry/ci
Browse files Browse the repository at this point in the history
ci
  • Loading branch information
bhperry authored Sep 18, 2024
2 parents 7eb5d64 + 50d95a3 commit e38bfbb
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 48 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: continuous integration
on: push

jobs:
cancel-previous:
name: Cancel previous runs
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}
lint:
name: Go lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.61.0
args: --verbose
test:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: Run tests
run: make test
runs-complete:
name: Lint and test
needs: [lint, test]
if: always()
runs-on: ubuntu-latest
steps:
- if: ${{ needs['lint'].result != 'success' || needs['test'].result != 'success' }}
name: Fail
run: exit 1
- name: Tests complete
run: echo "Tests complete"
5 changes: 5 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
run:
timeout: 5m
linters:
enable:
- gofmt
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ KUBEBUILDER_VERSION=1.28.0

HELM_FILES := $(shell find deploy/httpreq-webhook)

lint:
@golangci-lint run ./...

format:
@gofmt -l -w ./

test: _test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH)/etcd _test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH)/kube-apiserver _test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH)/kubectl
TEST_ASSET_ETCD=_test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH)/etcd \
TEST_ASSET_KUBE_APISERVER=_test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH)/kube-apiserver \
TEST_ASSET_KUBECTL=_test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH)/kubectl \
$(GO) test -v .
$(GO) test -v ./...

_test/kubebuilder-$(KUBEBUILDER_VERSION)-$(OS)-$(ARCH).tar.gz: | _test
curl -fsSL https://go.kubebuilder.io/test-tools/$(KUBEBUILDER_VERSION)/$(OS)/$(ARCH) -o $@
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ Webhook is built off of the [Cert Manager Webhook Example](https://github.com/ce
```bash
make test
```


### Linters

This repo uses golangci-lint. Follow the installation instructions [here](https://github.com/golangci/golangci-lint?tab=readme-ov-file#install-golangci-lint)
18 changes: 9 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/saturncloud/cert-manager-webhook-httpreq

go 1.22.0
go 1.22.7

require (
github.com/cert-manager/cert-manager v1.15.1
Expand Down Expand Up @@ -74,17 +74,17 @@ require (
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/term v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.org/x/tools v0.25.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect
Expand Down
32 changes: 16 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -201,46 +201,46 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
13 changes: 8 additions & 5 deletions httpreq/httpreq.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// package httpreq implements cert-manager webhook as an HTTP request to an external server
// Package httpreq implements cert-manager webhook as an HTTP request to an external server
// based on the lego httpreq solver https://go-acme.github.io/lego/dns/httpreq/
package httpreq

Expand Down Expand Up @@ -48,8 +48,8 @@ type IssuerConfig struct {
HeaderSecretRef struct{ Name, Namespace string } `json:"headerSecretRef"`
}

// GetUrl formats the endpoint URL for a given action
func (ic IssuerConfig) GetUrl(action acme.ChallengeAction) (string, error) {
// GetURL formats the endpoint URL for a given action
func (ic IssuerConfig) GetURL(action acme.ChallengeAction) (string, error) {
var path string
switch action {
case acme.ChallengeActionPresent:
Expand All @@ -75,6 +75,7 @@ func (ic IssuerConfig) GetUrl(action acme.ChallengeAction) (string, error) {
return url, nil
}

// New creates an httpreq solver and returns it as a cert-manager webook Solver interface
func New() webhook.Solver {
solver := &httpReqSolver{name: "httpreq", headers: http.Header{}}
if authorizationHeader != "" {
Expand Down Expand Up @@ -125,7 +126,7 @@ func (hrs *httpReqSolver) challengeRequest(ch *acme.ChallengeRequest) error {
return err
}

url, err := cfg.GetUrl(ch.Action)
url, err := cfg.GetURL(ch.Action)
if err != nil {
return err
}
Expand Down Expand Up @@ -158,7 +159,9 @@ func (hrs *httpReqSolver) challengeRequest(ch *acme.ChallengeRequest) error {

body := ChallengeBody{Fqdn: ch.ResolvedFQDN, Value: ch.Key}
var buffer bytes.Buffer
json.NewEncoder(&buffer).Encode(body)
if err = json.NewEncoder(&buffer).Encode(body); err != nil {
return err
}

request, err := http.NewRequest("POST", url, &buffer)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion httpreq/httpreq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestHttpReqSolver_Present_Cleanup(t *testing.T) {
err := solver.Initialize(nil, done)
assert.NoError(t, err, "Expected Initialize not to error")

mockEndpoint := mock.NewHttpReqEndpoint()
mockEndpoint := mock.NewHTTPReqEndpoint()
configData, err := json.Marshal(map[string]string{
"endpoint": mockEndpoint.URL(),
})
Expand Down
6 changes: 3 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
)

var (
GroupName = os.Getenv("GROUP_NAME")
groupName = os.Getenv("GROUP_NAME")
)

func main() {
if GroupName == "" {
if groupName == "" {
panic("GROUP_NAME must be specified")
}

Expand All @@ -22,7 +22,7 @@ func main() {
// webhook, where the Name() method will be used to disambiguate between
// the different implementations.
cmd.RunWebhookServer(
GroupName,
groupName,
httpreq.New(),
)
}
2 changes: 1 addition & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestRunsSuite(t *testing.T) {
acmetest.SetAllowAmbientCredentials(false),
}
if issuerConfig.Endpoint == "" {
mockEndpoint := mock.NewHttpReqEndpoint()
mockEndpoint := mock.NewHTTPReqEndpoint()
defer mockEndpoint.Close()

acmeOptions = append(
Expand Down
10 changes: 9 additions & 1 deletion mock/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ type DNS struct {
sync.RWMutex
}

// Addr returns the address of the mock DNS server
func (d *DNS) Addr() string {
return d.server.Addr
}

// Run initializes the mock DNS server
func (d *DNS) Run() {
go func() {
<-d.stop
Expand All @@ -51,17 +53,20 @@ func (d *DNS) Run() {
}()
}

// Close stops the mock DNS server
func (d *DNS) Close() {
close(d.stop)
}

// Present adds a TXT record to the mock DNS server
func (d *DNS) Present(fqdn, value string) {
d.Lock()
defer d.Unlock()

d.txtRecords[fqdn] = value
}

// Cleanup removes a TXT record from the mock DNS server
func (d *DNS) Cleanup(fqdn string) {
d.Lock()
defer d.Unlock()
Expand All @@ -81,7 +86,10 @@ func (d *DNS) handleDNSRequest(w dns.ResponseWriter, req *dns.Msg) {
}
}
}
w.WriteMsg(msg)
err := w.WriteMsg(msg)
if err != nil {
panic(err)
}
}

func (d *DNS) addDNSAnswer(q dns.Question, msg *dns.Msg, req *dns.Msg) error {
Expand Down
29 changes: 18 additions & 11 deletions mock/server.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package mock provides testing utilities for mocking an HTTPReq endpoint and DNS server
package mock

import (
Expand All @@ -6,34 +7,39 @@ import (
"net/http/httptest"
)

// NewHttpReqEndpoint creates a test httpreq endpoint and DNS server
func NewHttpReqEndpoint() *HttpReqEndpoint {
mock := &HttpReqEndpoint{}
mock.server = httptest.NewServer(mock)
// NewHTTPReqEndpoint creates a test httpreq endpoint and DNS server
func NewHTTPReqEndpoint() *HTTPReqEndpoint {
mock := &HTTPReqEndpoint{}
mock.server = httptest.NewServer(http.HandlerFunc(mock.serveHTTP))
mock.dns = NewMockDNS()
mock.dns.Run()
return mock
}

// HttpReqEndpoint is a test httpreq endpoint that creates and deletes DNS records in a test DNS server
type HttpReqEndpoint struct {
// HTTPReqEndpoint is a test httpreq endpoint that creates and deletes DNS records in a test DNS server
type HTTPReqEndpoint struct {
server *httptest.Server
dns *DNS
}

func (hre *HttpReqEndpoint) URL() string {
// URL returns the HTTP URL of the mock httpreq endpoint
func (hre *HTTPReqEndpoint) URL() string {
return hre.server.URL
}

func (hre *HttpReqEndpoint) DNS() *DNS {
// DNS returns the mock DNS server for the httpreq endpoint
func (hre *HTTPReqEndpoint) DNS() *DNS {
return hre.dns
}

func (hre *HttpReqEndpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (hre *HTTPReqEndpoint) serveHTTP(w http.ResponseWriter, r *http.Request) {
var body map[string]string
err := json.NewDecoder(r.Body).Decode(&body)
if err != nil {
w.Write([]byte(err.Error()))
_, err = w.Write([]byte(err.Error()))
if err != nil {
panic(err)
}
w.WriteHeader(http.StatusBadRequest)
return
}
Expand All @@ -47,7 +53,8 @@ func (hre *HttpReqEndpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
}

func (hre *HttpReqEndpoint) Close() {
// Close stops the test endpoint and DNS servers
func (hre *HTTPReqEndpoint) Close() {
hre.dns.Close()
hre.server.Close()
}

0 comments on commit e38bfbb

Please sign in to comment.