forked from TrueCloudLab/lego
option to specify gcloud service account json by env as string (#776)
Added the option to provide the gcloud service account as a string via the environment variable `GCE_SERVICE_ACCOUNT` in addition to the already available option to specify a filepath to a keyfile `GCE_SERVICE_ACCOUNT_FILE`.
This commit is contained in:
parent
68568b7ded
commit
0e6e4807b1
3 changed files with 36 additions and 18 deletions
|
@ -51,7 +51,7 @@ Here is an example bash command using the CloudFlare DNS provider:
|
||||||
fmt.Fprintln(w, "\tfastdns:\tAKAMAI_HOST, AKAMAI_CLIENT_TOKEN, AKAMAI_CLIENT_SECRET, AKAMAI_ACCESS_TOKEN")
|
fmt.Fprintln(w, "\tfastdns:\tAKAMAI_HOST, AKAMAI_CLIENT_TOKEN, AKAMAI_CLIENT_SECRET, AKAMAI_ACCESS_TOKEN")
|
||||||
fmt.Fprintln(w, "\tgandi:\tGANDI_API_KEY")
|
fmt.Fprintln(w, "\tgandi:\tGANDI_API_KEY")
|
||||||
fmt.Fprintln(w, "\tgandiv5:\tGANDIV5_API_KEY")
|
fmt.Fprintln(w, "\tgandiv5:\tGANDIV5_API_KEY")
|
||||||
fmt.Fprintln(w, "\tgcloud:\tGCE_PROJECT, 'Application Default Credentials', [GCE_SERVICE_ACCOUNT_FILE]")
|
fmt.Fprintln(w, "\tgcloud:\tGCE_PROJECT, 'Application Default Credentials', [GCE_SERVICE_ACCOUNT_FILE], [GCE_SERVICE_ACCOUNT]")
|
||||||
fmt.Fprintln(w, "\tglesys:\tGLESYS_API_USER, GLESYS_API_KEY")
|
fmt.Fprintln(w, "\tglesys:\tGLESYS_API_USER, GLESYS_API_KEY")
|
||||||
fmt.Fprintln(w, "\tgodaddy:\tGODADDY_API_KEY, GODADDY_API_SECRET")
|
fmt.Fprintln(w, "\tgodaddy:\tGODADDY_API_KEY, GODADDY_API_SECRET")
|
||||||
fmt.Fprintln(w, "\thostingde:\tHOSTINGDE_API_KEY, HOSTINGDE_ZONE_NAME")
|
fmt.Fprintln(w, "\thostingde:\tHOSTINGDE_API_KEY, HOSTINGDE_ZONE_NAME")
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -53,11 +52,12 @@ type DNSProvider struct {
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance configured for Google Cloud DNS.
|
// NewDNSProvider returns a DNSProvider instance configured for Google Cloud DNS.
|
||||||
// Project name must be passed in the environment variable: GCE_PROJECT.
|
// 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
|
// A Service Account can be passed in the environment variable: GCE_SERVICE_ACCOUNT
|
||||||
|
// or by specifying the keyfile location: GCE_SERVICE_ACCOUNT_FILE
|
||||||
func NewDNSProvider() (*DNSProvider, error) {
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
// Use a service account file if specified via environment variable.
|
// Use a service account file if specified via environment variable.
|
||||||
if saFile, ok := os.LookupEnv("GCE_SERVICE_ACCOUNT_FILE"); ok {
|
if saKey := env.GetOrFile("GCE_SERVICE_ACCOUNT"); len(saKey) > 0 {
|
||||||
return NewDNSProviderServiceAccount(saFile)
|
return NewDNSProviderServiceAccountKey([]byte(saKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use default credentials.
|
// Use default credentials.
|
||||||
|
@ -84,16 +84,11 @@ func NewDNSProviderCredentials(project string) (*DNSProvider, error) {
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProviderServiceAccount uses the supplied service account JSON file
|
// NewDNSProviderServiceAccountKey uses the supplied service account JSON
|
||||||
// to return a DNSProvider instance configured for Google Cloud DNS.
|
// to return a DNSProvider instance configured for Google Cloud DNS.
|
||||||
func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
func NewDNSProviderServiceAccountKey(saKey []byte) (*DNSProvider, error) {
|
||||||
if saFile == "" {
|
if len(saKey) == 0 {
|
||||||
return nil, fmt.Errorf("googlecloud: Service Account file missing")
|
return nil, fmt.Errorf("googlecloud: Service Account is missing")
|
||||||
}
|
|
||||||
|
|
||||||
dat, err := ioutil.ReadFile(saFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("googlecloud: unable to read Service Account file: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If GCE_PROJECT is non-empty it overrides the project in the service
|
// If GCE_PROJECT is non-empty it overrides the project in the service
|
||||||
|
@ -104,14 +99,14 @@ func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
||||||
var datJSON struct {
|
var datJSON struct {
|
||||||
ProjectID string `json:"project_id"`
|
ProjectID string `json:"project_id"`
|
||||||
}
|
}
|
||||||
err = json.Unmarshal(dat, &datJSON)
|
err := json.Unmarshal(saKey, &datJSON)
|
||||||
if err != nil || datJSON.ProjectID == "" {
|
if err != nil || datJSON.ProjectID == "" {
|
||||||
return nil, fmt.Errorf("googlecloud: project ID not found in Google Cloud Service Account file")
|
return nil, fmt.Errorf("googlecloud: project ID not found in Google Cloud Service Account file")
|
||||||
}
|
}
|
||||||
project = datJSON.ProjectID
|
project = datJSON.ProjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
conf, err := google.JWTConfigFromJSON(dat, dns.NdevClouddnsReadwriteScope)
|
conf, err := google.JWTConfigFromJSON(saKey, dns.NdevClouddnsReadwriteScope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("googlecloud: unable to acquire config: %v", err)
|
return nil, fmt.Errorf("googlecloud: unable to acquire config: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -124,6 +119,21 @@ func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
||||||
return NewDNSProviderConfig(config)
|
return NewDNSProviderConfig(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderServiceAccount uses the supplied service account JSON file
|
||||||
|
// to return a DNSProvider instance configured for Google Cloud DNS.
|
||||||
|
func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
||||||
|
if saFile == "" {
|
||||||
|
return nil, fmt.Errorf("googlecloud: Service Account file missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
saKey, err := ioutil.ReadFile(saFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("googlecloud: unable to read Service Account file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewDNSProviderServiceAccountKey(saKey)
|
||||||
|
}
|
||||||
|
|
||||||
// NewDNSProviderConfig return a DNSProvider instance configured for Google Cloud DNS.
|
// NewDNSProviderConfig return a DNSProvider instance configured for Google Cloud DNS.
|
||||||
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
|
|
|
@ -19,7 +19,8 @@ import (
|
||||||
var envTest = tester.NewEnvTest(
|
var envTest = tester.NewEnvTest(
|
||||||
"GCE_PROJECT",
|
"GCE_PROJECT",
|
||||||
"GCE_SERVICE_ACCOUNT_FILE",
|
"GCE_SERVICE_ACCOUNT_FILE",
|
||||||
"GOOGLE_APPLICATION_CREDENTIALS").
|
"GOOGLE_APPLICATION_CREDENTIALS",
|
||||||
|
"GCE_SERVICE_ACCOUNT").
|
||||||
WithDomain("GCE_DOMAIN").
|
WithDomain("GCE_DOMAIN").
|
||||||
WithLiveTestExtra(func() bool {
|
WithLiveTestExtra(func() bool {
|
||||||
_, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope)
|
_, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope)
|
||||||
|
@ -51,12 +52,19 @@ func TestNewDNSProvider(t *testing.T) {
|
||||||
expected: "googlecloud: project name missing",
|
expected: "googlecloud: project name missing",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "success",
|
desc: "success key file",
|
||||||
envVars: map[string]string{
|
envVars: map[string]string{
|
||||||
"GCE_PROJECT": "",
|
"GCE_PROJECT": "",
|
||||||
"GCE_SERVICE_ACCOUNT_FILE": "fixtures/gce_account_service_file.json",
|
"GCE_SERVICE_ACCOUNT_FILE": "fixtures/gce_account_service_file.json",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "success key",
|
||||||
|
envVars: map[string]string{
|
||||||
|
"GCE_PROJECT": "",
|
||||||
|
"GCE_SERVICE_ACCOUNT": `{"project_id": "A","type": "service_account","client_email": "foo@bar.com","private_key_id": "pki","private_key": "pk","token_uri": "/token","client_secret": "secret","client_id": "C","refresh_token": "D"}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
|
Loading…
Reference in a new issue