2018-03-27 16:10:38 +02:00
|
|
|
package exec
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2018-07-18 01:19:48 +02:00
|
|
|
"fmt"
|
2018-03-27 16:10:38 +02:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/xenolf/lego/acme"
|
2018-07-18 01:19:48 +02:00
|
|
|
"github.com/xenolf/lego/log"
|
|
|
|
"github.com/xenolf/lego/platform/config/env"
|
2018-03-27 16:10:38 +02:00
|
|
|
)
|
|
|
|
|
2018-07-18 01:19:48 +02:00
|
|
|
// Config Provider configuration.
|
|
|
|
type Config struct {
|
|
|
|
Program string
|
|
|
|
Mode string
|
|
|
|
}
|
|
|
|
|
2018-03-27 16:10:38 +02:00
|
|
|
// DNSProvider adds and removes the record for the DNS challenge by calling a
|
|
|
|
// program with command-line parameters.
|
|
|
|
type DNSProvider struct {
|
2018-07-18 01:19:48 +02:00
|
|
|
config *Config
|
2018-03-27 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewDNSProvider returns a new DNS provider which runs the program in the
|
|
|
|
// environment variable EXEC_PATH for adding and removing the DNS record.
|
|
|
|
func NewDNSProvider() (*DNSProvider, error) {
|
2018-07-18 01:19:48 +02:00
|
|
|
values, err := env.Get("EXEC_PATH")
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("exec: %v", err)
|
2018-03-27 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
2018-07-18 01:19:48 +02:00
|
|
|
return NewDNSProviderConfig(&Config{
|
|
|
|
Program: values["EXEC_PATH"],
|
|
|
|
Mode: os.Getenv("EXEC_MODE"),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewDNSProviderConfig returns a new DNS provider which runs the given configuration
|
|
|
|
// for adding and removing the DNS record.
|
|
|
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
|
|
|
if config == nil {
|
|
|
|
return nil, errors.New("the configuration is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
return &DNSProvider{config: config}, nil
|
2018-06-10 21:51:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewDNSProviderProgram returns a new DNS provider which runs the given program
|
|
|
|
// for adding and removing the DNS record.
|
2018-07-18 01:19:48 +02:00
|
|
|
// Deprecated: use NewDNSProviderConfig instead
|
2018-06-10 21:51:01 +02:00
|
|
|
func NewDNSProviderProgram(program string) (*DNSProvider, error) {
|
2018-07-18 01:19:48 +02:00
|
|
|
if len(program) == 0 {
|
|
|
|
return nil, errors.New("the program is undefined")
|
|
|
|
}
|
|
|
|
|
|
|
|
return NewDNSProviderConfig(&Config{Program: program})
|
2018-03-27 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Present creates a TXT record to fulfil the dns-01 challenge.
|
|
|
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
2018-07-18 01:19:48 +02:00
|
|
|
var args []string
|
|
|
|
if d.config.Mode == "RAW" {
|
|
|
|
args = []string{"present", "--", domain, token, keyAuth}
|
|
|
|
} else {
|
|
|
|
fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
|
|
|
|
args = []string{"present", fqdn, value, strconv.Itoa(ttl)}
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd := exec.Command(d.config.Program, args...)
|
|
|
|
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
if len(output) > 0 {
|
|
|
|
log.Println(string(output))
|
|
|
|
}
|
2018-03-27 16:10:38 +02:00
|
|
|
|
2018-07-18 01:19:48 +02:00
|
|
|
return err
|
2018-03-27 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// CleanUp removes the TXT record matching the specified parameters
|
|
|
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
2018-07-18 01:19:48 +02:00
|
|
|
var args []string
|
|
|
|
if d.config.Mode == "RAW" {
|
|
|
|
args = []string{"cleanup", "--", domain, token, keyAuth}
|
|
|
|
} else {
|
|
|
|
fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
|
|
|
|
args = []string{"cleanup", fqdn, value, strconv.Itoa(ttl)}
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd := exec.Command(d.config.Program, args...)
|
|
|
|
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
if len(output) > 0 {
|
|
|
|
log.Println(string(output))
|
|
|
|
}
|
2018-03-27 16:10:38 +02:00
|
|
|
|
2018-07-18 01:19:48 +02:00
|
|
|
return err
|
2018-03-27 16:10:38 +02:00
|
|
|
}
|