Skip to content

Commit

Permalink
Notify client about renewals
Browse files Browse the repository at this point in the history
  • Loading branch information
evenh committed Apr 27, 2019
1 parent d1f7123 commit a2926c6
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 34 deletions.
182 changes: 165 additions & 17 deletions api/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions api/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,21 @@ message PingResponse {
string msg = 2;
}

message CertificateRenewalNotificationRequest {
// A list of DNS names to monitor for renewals
repeated string dnsNames = 1;
}

// Response for a certificate that has been renewed on the server
message RenewedCertificateEvent {
// Example: foo.bar.com
string dnsName = 1;
}

service CertificateIssuer {
rpc IssueCert (CertificateRequest) returns (CertificateResponse) {
}
rpc Ping (PingRequest) returns (PingResponse) {
}
rpc OnCertificateRenewal (CertificateRenewalNotificationRequest) returns (stream RenewedCertificateEvent) {}
}
3 changes: 2 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,10 @@ func configureTasks(client api.CertificateIssuerClient, config *config.ClientCon
var tasks []Job

pinger := *Register(pingServer(client), "Ping intercert host", 10*time.Minute, false)
renewalHandler := *Register(watchForEvents(config.Domains, client), "Watch for certificate renewal events", 0 * time.Second, true)
desiredCheck := *Register(ensureCertsFromConfig(storage, config.Domains), "Ensure configured domains is present", 1*time.Hour, true)

tasks = append(tasks, pinger, desiredCheck)
tasks = append(tasks, pinger, renewalHandler, desiredCheck)

return tasks
}
30 changes: 16 additions & 14 deletions client/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,23 @@ func (j *Job) start() {
}
j.firstRun = false

go func() {
for {
// Sleep for the predetermined time.
time.Sleep(j.delay)

select {
// Check for the 'stop' signal.
case <-j.stop:
return
// Execute the function.
default:
j.fn()
if j.delay > 0 * time.Second {
go func() {
for {
// Sleep for the predetermined time.
time.Sleep(j.delay)

select {
// Check for the 'stop' signal.
case <-j.stop:
return
// Execute the function.
default:
j.fn()
}
}
}
}()
}()
}
}

// Register schedules a function for execution, to be invoked repeated with a delay of
Expand Down
36 changes: 36 additions & 0 deletions client/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"github.com/evenh/intercert/api"
"github.com/go-acme/lego/log"
"io"
"os"
)

func pingServer(client api.CertificateIssuerClient) func() {
Expand All @@ -16,6 +18,40 @@ func pingServer(client api.CertificateIssuerClient) func() {
}
}

func watchForEvents(domains []string, client api.CertificateIssuerClient) func() {
return func() {
renewalStream, err := client.OnCertificateRenewal(context.Background(), &api.CertificateRenewalNotificationRequest{
DnsNames: domains,
})

if err != nil {
log.Fatalf("Could not subscribe to renewal events: %v", err)
os.Exit(1)
}

log.Infof("Listening for certificate renewal events")

go func() {
for {
in, err := renewalStream.Recv()

if err == io.EOF {
break
}

if err != nil {
log.Warnf("Got error while listening for renewal events: %v", err)
}

log.Infof("Got notice from server that certificate for %s has been renewed. Queuing up re-fetch!", in.DnsName)
job := NewCertReq(in.DnsName, true)
job.Submit()
}
}()

}
}

// Check that every cert from the config is present in the file system
func ensureCertsFromConfig(storage *CertStorage, wantedDomains []string) func() {
return func() {
Expand Down
Loading

0 comments on commit a2926c6

Please sign in to comment.