mirror of
https://github.com/cert-manager/webhook-example.git
synced 2025-07-03 23:25:49 +02:00
cleanup
This commit is contained in:
parent
79834dee3c
commit
daaeb094ce
6 changed files with 0 additions and 253 deletions
16
OWNERS
16
OWNERS
|
@ -1,16 +0,0 @@
|
||||||
approvers:
|
|
||||||
- munnerz
|
|
||||||
- joshvanl
|
|
||||||
- meyskens
|
|
||||||
- wallrj
|
|
||||||
- jakexks
|
|
||||||
- maelvls
|
|
||||||
- irbekrm
|
|
||||||
reviewers:
|
|
||||||
- munnerz
|
|
||||||
- joshvanl
|
|
||||||
- meyskens
|
|
||||||
- wallrj
|
|
||||||
- jakexks
|
|
||||||
- maelvls
|
|
||||||
- irbekrm
|
|
|
@ -1,69 +0,0 @@
|
||||||
package example
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (e *exampleSolver) handleDNSRequest(w dns.ResponseWriter, req *dns.Msg) {
|
|
||||||
msg := new(dns.Msg)
|
|
||||||
msg.SetReply(req)
|
|
||||||
switch req.Opcode {
|
|
||||||
case dns.OpcodeQuery:
|
|
||||||
for _, q := range msg.Question {
|
|
||||||
if err := e.addDNSAnswer(q, msg, req); err != nil {
|
|
||||||
msg.SetRcode(req, dns.RcodeServerFailure)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.WriteMsg(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *exampleSolver) addDNSAnswer(q dns.Question, msg *dns.Msg, req *dns.Msg) error {
|
|
||||||
switch q.Qtype {
|
|
||||||
// Always return loopback for any A query
|
|
||||||
case dns.TypeA:
|
|
||||||
rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN A 127.0.0.1", q.Name))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
msg.Answer = append(msg.Answer, rr)
|
|
||||||
return nil
|
|
||||||
|
|
||||||
// TXT records are the only important record for ACME dns-01 challenges
|
|
||||||
case dns.TypeTXT:
|
|
||||||
e.RLock()
|
|
||||||
record, found := e.txtRecords[q.Name]
|
|
||||||
e.RUnlock()
|
|
||||||
if !found {
|
|
||||||
msg.SetRcode(req, dns.RcodeNameError)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN TXT %s", q.Name, record))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
msg.Answer = append(msg.Answer, rr)
|
|
||||||
return nil
|
|
||||||
|
|
||||||
// NS and SOA are for authoritative lookups, return obviously invalid data
|
|
||||||
case dns.TypeNS:
|
|
||||||
rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN NS ns.example-acme-webook.invalid.", q.Name))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
msg.Answer = append(msg.Answer, rr)
|
|
||||||
return nil
|
|
||||||
case dns.TypeSOA:
|
|
||||||
rr, err := dns.NewRR(fmt.Sprintf("%s 5 IN SOA %s 20 5 5 5 5", "ns.example-acme-webook.invalid.", "ns.example-acme-webook.invalid."))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
msg.Answer = append(msg.Answer, rr)
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unimplemented record type %v", q.Qtype)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
// package example contains a self-contained example of a webhook that passes the cert-manager
|
|
||||||
// DNS conformance tests
|
|
||||||
package example
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/jetstack/cert-manager/pkg/acme/webhook"
|
|
||||||
acme "github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
"k8s.io/client-go/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
type exampleSolver struct {
|
|
||||||
name string
|
|
||||||
server *dns.Server
|
|
||||||
txtRecords map[string]string
|
|
||||||
sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *exampleSolver) Name() string {
|
|
||||||
return e.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *exampleSolver) Present(ch *acme.ChallengeRequest) error {
|
|
||||||
e.Lock()
|
|
||||||
e.txtRecords[ch.ResolvedFQDN] = ch.Key
|
|
||||||
e.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *exampleSolver) CleanUp(ch *acme.ChallengeRequest) error {
|
|
||||||
e.Lock()
|
|
||||||
delete(e.txtRecords, ch.ResolvedFQDN)
|
|
||||||
e.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *exampleSolver) Initialize(kubeClientConfig *rest.Config, stopCh <-chan struct{}) error {
|
|
||||||
go func(done <-chan struct{}) {
|
|
||||||
<-done
|
|
||||||
if err := e.server.Shutdown(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
}
|
|
||||||
}(stopCh)
|
|
||||||
go func() {
|
|
||||||
if err := e.server.ListenAndServe(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(port string) webhook.Solver {
|
|
||||||
e := &exampleSolver{
|
|
||||||
name: "example",
|
|
||||||
txtRecords: make(map[string]string),
|
|
||||||
}
|
|
||||||
e.server = &dns.Server{
|
|
||||||
Addr: ":" + port,
|
|
||||||
Net: "udp",
|
|
||||||
Handler: dns.HandlerFunc(e.handleDNSRequest),
|
|
||||||
}
|
|
||||||
return e
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package example
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"math/big"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
acme "github.com/jetstack/cert-manager/pkg/acme/webhook/apis/acme/v1alpha1"
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestExampleSolver_Name(t *testing.T) {
|
|
||||||
port, _ := rand.Int(rand.Reader, big.NewInt(50000))
|
|
||||||
port = port.Add(port, big.NewInt(15534))
|
|
||||||
solver := New(port.String())
|
|
||||||
assert.Equal(t, "example", solver.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExampleSolver_Initialize(t *testing.T) {
|
|
||||||
port, _ := rand.Int(rand.Reader, big.NewInt(50000))
|
|
||||||
port = port.Add(port, big.NewInt(15534))
|
|
||||||
solver := New(port.String())
|
|
||||||
done := make(chan struct{})
|
|
||||||
err := solver.Initialize(nil, done)
|
|
||||||
assert.NoError(t, err, "Expected Initialize not to error")
|
|
||||||
close(done)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExampleSolver_Present_Cleanup(t *testing.T) {
|
|
||||||
port, _ := rand.Int(rand.Reader, big.NewInt(50000))
|
|
||||||
port = port.Add(port, big.NewInt(15534))
|
|
||||||
solver := New(port.String())
|
|
||||||
done := make(chan struct{})
|
|
||||||
err := solver.Initialize(nil, done)
|
|
||||||
assert.NoError(t, err, "Expected Initialize not to error")
|
|
||||||
|
|
||||||
validTestData := []struct {
|
|
||||||
hostname string
|
|
||||||
record string
|
|
||||||
}{
|
|
||||||
{"test1.example.com.", "testkey1"},
|
|
||||||
{"test2.example.com.", "testkey2"},
|
|
||||||
{"test3.example.com.", "testkey3"},
|
|
||||||
}
|
|
||||||
for _, test := range validTestData {
|
|
||||||
err := solver.Present(&acme.ChallengeRequest{
|
|
||||||
Action: acme.ChallengeActionPresent,
|
|
||||||
Type: "dns-01",
|
|
||||||
ResolvedFQDN: test.hostname,
|
|
||||||
Key: test.record,
|
|
||||||
})
|
|
||||||
assert.NoError(t, err, "Unexpected error while presenting %v", t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve test data
|
|
||||||
for _, test := range validTestData {
|
|
||||||
msg := new(dns.Msg)
|
|
||||||
msg.Id = dns.Id()
|
|
||||||
msg.RecursionDesired = true
|
|
||||||
msg.Question = make([]dns.Question, 1)
|
|
||||||
msg.Question[0] = dns.Question{dns.Fqdn(test.hostname), dns.TypeTXT, dns.ClassINET}
|
|
||||||
in, err := dns.Exchange(msg, "127.0.0.1:"+port.String())
|
|
||||||
|
|
||||||
assert.NoError(t, err, "Presented record %s not resolvable", test.hostname)
|
|
||||||
assert.Len(t, in.Answer, 1, "RR response is of incorrect length")
|
|
||||||
assert.Equal(t, []string{test.record}, in.Answer[0].(*dns.TXT).Txt, "TXT record returned did not match presented record")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup test data
|
|
||||||
for _, test := range validTestData {
|
|
||||||
err := solver.CleanUp(&acme.ChallengeRequest{
|
|
||||||
Action: acme.ChallengeActionCleanUp,
|
|
||||||
Type: "dns-01",
|
|
||||||
ResolvedFQDN: test.hostname,
|
|
||||||
Key: test.record,
|
|
||||||
})
|
|
||||||
assert.NoError(t, err, "Unexpected error while cleaning up %v", t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve test data
|
|
||||||
for _, test := range validTestData {
|
|
||||||
msg := new(dns.Msg)
|
|
||||||
msg.Id = dns.Id()
|
|
||||||
msg.RecursionDesired = true
|
|
||||||
msg.Question = make([]dns.Question, 1)
|
|
||||||
msg.Question[0] = dns.Question{dns.Fqdn(test.hostname), dns.TypeTXT, dns.ClassINET}
|
|
||||||
in, err := dns.Exchange(msg, "127.0.0.1:"+port.String())
|
|
||||||
|
|
||||||
assert.NoError(t, err, "Presented record %s not resolvable", test.hostname)
|
|
||||||
assert.Len(t, in.Answer, 0, "RR response is of incorrect length")
|
|
||||||
assert.Equal(t, dns.RcodeNameError, in.Rcode, "Expexted NXDOMAIN")
|
|
||||||
}
|
|
||||||
|
|
||||||
close(done)
|
|
||||||
}
|
|
3
testdata/my-custom-solver/README.md
vendored
3
testdata/my-custom-solver/README.md
vendored
|
@ -1,3 +0,0 @@
|
||||||
# Solver testdata directory
|
|
||||||
|
|
||||||
TODO
|
|
1
testdata/my-custom-solver/config.json
vendored
1
testdata/my-custom-solver/config.json
vendored
|
@ -1 +0,0 @@
|
||||||
{}
|
|
Loading…
Reference in a new issue