forked from TrueCloudLab/lego
RFC: providers/dns: add Service Account authorization option to gcloud (#408)
* providers/dns: add Service Account authorization option to gcloud * providers/dns: use os.LookupEnv() for local ENV var
This commit is contained in:
parent
192334c448
commit
dd74b99f8d
4 changed files with 41 additions and 4 deletions
2
cli.go
2
cli.go
|
@ -209,7 +209,7 @@ Here is an example bash command using the CloudFlare DNS provider:
|
||||||
fmt.Fprintln(w, "\tdnsmadeeasy:\tDNSMADEEASY_API_KEY, DNSMADEEASY_API_SECRET")
|
fmt.Fprintln(w, "\tdnsmadeeasy:\tDNSMADEEASY_API_KEY, DNSMADEEASY_API_SECRET")
|
||||||
fmt.Fprintln(w, "\texoscale:\tEXOSCALE_API_KEY, EXOSCALE_API_SECRET, EXOSCALE_ENDPOINT")
|
fmt.Fprintln(w, "\texoscale:\tEXOSCALE_API_KEY, EXOSCALE_API_SECRET, EXOSCALE_ENDPOINT")
|
||||||
fmt.Fprintln(w, "\tgandi:\tGANDI_API_KEY")
|
fmt.Fprintln(w, "\tgandi:\tGANDI_API_KEY")
|
||||||
fmt.Fprintln(w, "\tgcloud:\tGCE_PROJECT")
|
fmt.Fprintln(w, "\tgcloud:\tGCE_PROJECT, GCE_SERVICE_ACCOUNT_FILE")
|
||||||
fmt.Fprintln(w, "\tlinode:\tLINODE_API_KEY")
|
fmt.Fprintln(w, "\tlinode:\tLINODE_API_KEY")
|
||||||
fmt.Fprintln(w, "\tmanual:\tnone")
|
fmt.Fprintln(w, "\tmanual:\tnone")
|
||||||
fmt.Fprintln(w, "\tnamecheap:\tNAMECHEAP_API_USER, NAMECHEAP_API_KEY")
|
fmt.Fprintln(w, "\tnamecheap:\tNAMECHEAP_API_USER, NAMECHEAP_API_KEY")
|
||||||
|
|
|
@ -114,7 +114,7 @@ func setup(c *cli.Context) (*Configuration, *Account, *acme.Client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.GlobalIsSet("dns") {
|
if c.GlobalIsSet("dns") {
|
||||||
provider, err := dns.NewDNSChallengeProviderByName(c.GlobalString("dns"))
|
provider, err := dns.NewDNSChallengeProviderByName(c.GlobalString("dns"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger().Fatal(err)
|
logger().Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func NewDNSChallengeProviderByName(name string) (acme.ChallengeProvider, error)
|
||||||
case "dyn":
|
case "dyn":
|
||||||
provider, err = dyn.NewDNSProvider()
|
provider, err = dyn.NewDNSProvider()
|
||||||
case "exoscale":
|
case "exoscale":
|
||||||
provider, err = exoscale.NewDNSProvider()
|
provider, err = exoscale.NewDNSProvider()
|
||||||
case "gandi":
|
case "gandi":
|
||||||
provider, err = gandi.NewDNSProvider()
|
provider, err = gandi.NewDNSProvider()
|
||||||
case "gcloud":
|
case "gcloud":
|
||||||
|
|
|
@ -4,12 +4,14 @@ package googlecloud
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/xenolf/lego/acme"
|
"github.com/xenolf/lego/acme"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
|
|
||||||
"google.golang.org/api/dns/v1"
|
"google.golang.org/api/dns/v1"
|
||||||
|
@ -22,9 +24,14 @@ type DNSProvider struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance configured for Google Cloud
|
// NewDNSProvider returns a DNSProvider instance configured for Google Cloud
|
||||||
// DNS. Credentials must be passed in the environment variable: GCE_PROJECT.
|
// DNS. Project name must be passed in the environment variable: GCE_PROJECT.
|
||||||
|
// A Service Account file can be passed in the environment variable:
|
||||||
|
// GCE_SERVICE_ACCOUNT_FILE
|
||||||
func NewDNSProvider() (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
project := os.Getenv("GCE_PROJECT")
|
project := os.Getenv("GCE_PROJECT")
|
||||||
|
if saFile, ok := os.LookupEnv("GCE_SERVICE_ACCOUNT_FILE"); ok {
|
||||||
|
return NewDNSProviderServiceAccount(project, saFile)
|
||||||
|
}
|
||||||
return NewDNSProviderCredentials(project)
|
return NewDNSProviderCredentials(project)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +56,36 @@ func NewDNSProviderCredentials(project string) (*DNSProvider, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderServiceAccount uses the supplied service account JSON file to
|
||||||
|
// return a DNSProvider instance configured for Google Cloud DNS.
|
||||||
|
func NewDNSProviderServiceAccount(project string, saFile string) (*DNSProvider, error) {
|
||||||
|
if project == "" {
|
||||||
|
return nil, fmt.Errorf("Google Cloud project name missing")
|
||||||
|
}
|
||||||
|
if saFile == "" {
|
||||||
|
return nil, fmt.Errorf("Google Cloud Service Account file missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
dat, err := ioutil.ReadFile(saFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to read Service Account file: %v", err)
|
||||||
|
}
|
||||||
|
conf, err := google.JWTConfigFromJSON(dat, dns.NdevClouddnsReadwriteScope)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to acquire config: %v", err)
|
||||||
|
}
|
||||||
|
client := conf.Client(oauth2.NoContext)
|
||||||
|
|
||||||
|
svc, err := dns.New(client)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to create Google Cloud DNS service: %v", err)
|
||||||
|
}
|
||||||
|
return &DNSProvider{
|
||||||
|
project: project,
|
||||||
|
client: svc,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Present creates a TXT record to fulfil the dns-01 challenge.
|
// Present creates a TXT record to fulfil the dns-01 challenge.
|
||||||
func (c *DNSProvider) Present(domain, token, keyAuth string) error {
|
func (c *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
|
fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
|
||||||
|
|
Loading…
Add table
Reference in a new issue