Skip to content

Commit

Permalink
domain_record added, 0.0.1 version
Browse files Browse the repository at this point in the history
  • Loading branch information
hypersleep committed Jul 27, 2016
1 parent 6dff552 commit 56c36cc
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 161 deletions.
171 changes: 171 additions & 0 deletions domain_record.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package main

import(
"fmt"
"net"
"time"
"crypto"
"crypto/elliptic"
"crypto/rand"
"crypto/ecdsa"
"errors"
"strconv"
"encoding/json"

"github.com/xenolf/lego/acme"
consul "github.com/hashicorp/consul/api"
)

type(
DomainRecord struct {
Domains []string `consul:"domains"`
Email string `consul:"email"`
Timestamp time.Time `consul:"timestamp"`
PrivateKey string `consul:"private_key"`
Fullchain string `consul:"fullchain"`
key *ecdsa.PrivateKey
Reg *acme.RegistrationResource
}
)

func (domainRecord *DomainRecord) GetEmail() string { return domainRecord.Email }
func (domainRecord *DomainRecord) GetRegistration() *acme.RegistrationResource { return domainRecord.Reg }
func (domainRecord *DomainRecord) GetPrivateKey() crypto.PrivateKey { return domainRecord.key }

func (domainRecord *DomainRecord) write(client *consul.Client, consulService string, domainRecordName string) error {
kv := client.KV()

timestamp := domainRecord.Timestamp.Unix()
timestampStr := strconv.Itoa(int(timestamp))

p := &consul.KVPair {
Key: consulService + "/domains/" + domainRecordName + "/timestamp",
Value: []byte(timestampStr),
}
_, err := kv.Put(p, nil)
if err != nil {
return err
}

p = &consul.KVPair {
Key: consulService + "/domains/" + domainRecordName + "/fullchain",
Value: []byte(domainRecord.Fullchain),
}
_, err = kv.Put(p, nil)
if err != nil {
return err
}

p = &consul.KVPair {
Key: consulService + "/domains/" + domainRecordName + "/private_key",
Value: []byte(domainRecord.PrivateKey),
}
_, err = kv.Put(p, nil)
if err != nil {
return err
}

return nil
}

func (domainRecord *DomainRecord) renew(bind string) error {
const letsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"

key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
return err
}

domainRecord.key = key

client, err := acme.NewClient(letsEncryptURL, domainRecord, acme.EC256)
if err != nil {
return err
}

reg, err := client.Register()
if err != nil {
return err
}

domainRecord.Reg = reg

err = client.AgreeToTOS()
if err != nil {
return err
}

host, port, err := net.SplitHostPort(bind)
if err != nil {
return err
}

client.ExcludeChallenges([]acme.Challenge{acme.TLSSNI01})
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01})

httpProvider := acme.NewHTTPProviderServer(host, port)

err = client.SetChallengeProvider(acme.HTTP01, httpProvider)
if err != nil {
return err
}

acmeCert, errmap := client.ObtainCertificate(domainRecord.Domains, true, nil)
if len(errmap) > 0 {
err = fmt.Errorf("%v", errmap)
return err
}

domainRecord.Fullchain = string(acmeCert.Certificate)
domainRecord.PrivateKey = string(acmeCert.PrivateKey)

domainRecord.Timestamp = time.Now()

return nil
}

func kvFetch(kv *consul.KV, prefix string, domainRecordName string, key string) ([]byte, error) {
kvPair, _, err := kv.Get(prefix + "/domains/" + domainRecordName + "/" + key, nil)
if err != nil {
return nil, err
}

if kvPair == nil {
return nil, errors.New("Can't fetch '" + key + "' key from '" + domainRecordName + "' domain")
}

return kvPair.Value, nil
}

func (domainRecord *DomainRecord) get(kv *consul.KV, prefix string, domainRecordName string) error {
v, err := kvFetch(kv, prefix, domainRecordName, "domain_list")
if err != nil {
return err
}

err = json.Unmarshal(v, &domainRecord.Domains)
if err != nil {
return err
}

v, err = kvFetch(kv, prefix, domainRecordName, "email")
if err != nil {
return err
}

domainRecord.Email = string(v)

v, err = kvFetch(kv, prefix, domainRecordName, "timestamp")
if err != nil {
return err
}

i, err := strconv.ParseInt(string(v), 10, 64)
if err != nil {
return err
}

domainRecord.Timestamp = time.Unix(i, 0)

return nil
}
161 changes: 0 additions & 161 deletions letsconsul.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
package main

import(
"fmt"
"net"
"time"
"crypto"
"crypto/elliptic"
"crypto/rand"
"crypto/ecdsa"
"errors"
"strconv"
"encoding/json"

"github.com/xenolf/lego/acme"
consul "github.com/hashicorp/consul/api"
)

Expand All @@ -21,114 +13,8 @@ type(
Bind string
Domains map[string]*DomainRecord
}

DomainRecord struct {
Domains []string `consul:"domains"`
Email string `consul:"email"`
Timestamp time.Time `consul:"timestamp"`
PrivateKey string `consul:"private_key"`
Fullchain string `consul:"fullchain"`
key *ecdsa.PrivateKey
Reg *acme.RegistrationResource
}
)

func (domainRecord *DomainRecord) GetEmail() string { return domainRecord.Email }
func (domainRecord *DomainRecord) GetRegistration() *acme.RegistrationResource { return domainRecord.Reg }
func (domainRecord *DomainRecord) GetPrivateKey() crypto.PrivateKey { return domainRecord.key }

func (domainRecord *DomainRecord) write(client *consul.Client, consulService string, domainRecordName string) error {
kv := client.KV()

timestamp := domainRecord.Timestamp.Unix()
timestampStr := strconv.Itoa(int(timestamp))

p := &consul.KVPair {
Key: consulService + "/domains/" + domainRecordName + "/timestamp",
Value: []byte(timestampStr),
}
_, err := kv.Put(p, nil)
if err != nil {
return err
}

p = &consul.KVPair {
Key: consulService + "/domains/" + domainRecordName + "/fullchain",
Value: []byte(domainRecord.Fullchain),
}
_, err = kv.Put(p, nil)
if err != nil {
return err
}

p = &consul.KVPair {
Key: consulService + "/domains/" + domainRecordName + "/private_key",
Value: []byte(domainRecord.PrivateKey),
}
_, err = kv.Put(p, nil)
if err != nil {
return err
}

return nil
}

func (domainRecord *DomainRecord) renew(bind string) error {
const letsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"

key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {
return err
}

domainRecord.key = key

client, err := acme.NewClient(letsEncryptURL, domainRecord, acme.EC256)
if err != nil {
return err
}

reg, err := client.Register()
if err != nil {
return err
}

domainRecord.Reg = reg

err = client.AgreeToTOS()
if err != nil {
return err
}

host, port, err := net.SplitHostPort(bind)
if err != nil {
return err
}

client.ExcludeChallenges([]acme.Challenge{acme.TLSSNI01})
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01})

httpProvider := acme.NewHTTPProviderServer(host, port)

err = client.SetChallengeProvider(acme.HTTP01, httpProvider)
if err != nil {
return err
}

acmeCert, errmap := client.ObtainCertificate(domainRecord.Domains, true, nil)
if len(errmap) > 0 {
err = fmt.Errorf("%v", errmap)
return err
}

domainRecord.Fullchain = string(acmeCert.Certificate)
domainRecord.PrivateKey = string(acmeCert.PrivateKey)

domainRecord.Timestamp = time.Now()

return nil
}

func (letsconsul *Letsconsul) renew(client *consul.Client, consulService string, renewInterval time.Duration) error {
for domainRecordName, domainRecord := range letsconsul.Domains {
if domainRecord.Timestamp.Add(renewInterval).Before(time.Now()) {
Expand All @@ -146,52 +32,6 @@ func (letsconsul *Letsconsul) renew(client *consul.Client, consulService string,
return nil
}

func kvFetch(kv *consul.KV, prefix string, domainRecordName string, key string) ([]byte, error) {
kvPair, _, err := kv.Get(prefix + "/domains/" + domainRecordName + "/" + key, nil)
if err != nil {
return nil, err
}

if kvPair == nil {
return nil, errors.New("Can't fetch '" + key + "' key from '" + domainRecordName + "' domain")
}

return kvPair.Value, nil
}

func (domainRecord *DomainRecord) get(kv *consul.KV, prefix string, domainRecordName string) error {
v, err := kvFetch(kv, prefix, domainRecordName, "domain_list")
if err != nil {
return err
}

err = json.Unmarshal(v, &domainRecord.Domains)
if err != nil {
return err
}

v, err = kvFetch(kv, prefix, domainRecordName, "email")
if err != nil {
return err
}

domainRecord.Email = string(v)

v, err = kvFetch(kv, prefix, domainRecordName, "timestamp")
if err != nil {
return err
}

i, err := strconv.ParseInt(string(v), 10, 64)
if err != nil {
return err
}

domainRecord.Timestamp = time.Unix(i, 0)

return nil
}

func (letsconsul *Letsconsul) get(client *consul.Client, prefix string) error {
kv := client.KV()

Expand Down Expand Up @@ -221,6 +61,5 @@ func (letsconsul *Letsconsul) get(client *consul.Client, prefix string) error {
letsconsul.Domains[domainsEnabled[i]] = domainRecord
}
}

return nil
}

0 comments on commit 56c36cc

Please sign in to comment.