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, "\tgandi:\tGANDI_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, "\tgodaddy:\tGODADDY_API_KEY, GODADDY_API_SECRET")
|
||||
fmt.Fprintln(w, "\thostingde:\tHOSTINGDE_API_KEY, HOSTINGDE_ZONE_NAME")
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
@ -53,11 +52,12 @@ type DNSProvider struct {
|
|||
|
||||
// NewDNSProvider returns a DNSProvider instance configured for Google Cloud 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
|
||||
// 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) {
|
||||
// Use a service account file if specified via environment variable.
|
||||
if saFile, ok := os.LookupEnv("GCE_SERVICE_ACCOUNT_FILE"); ok {
|
||||
return NewDNSProviderServiceAccount(saFile)
|
||||
if saKey := env.GetOrFile("GCE_SERVICE_ACCOUNT"); len(saKey) > 0 {
|
||||
return NewDNSProviderServiceAccountKey([]byte(saKey))
|
||||
}
|
||||
|
||||
// Use default credentials.
|
||||
|
@ -84,16 +84,11 @@ func NewDNSProviderCredentials(project string) (*DNSProvider, error) {
|
|||
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.
|
||||
func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
||||
if saFile == "" {
|
||||
return nil, fmt.Errorf("googlecloud: Service Account file missing")
|
||||
}
|
||||
|
||||
dat, err := ioutil.ReadFile(saFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("googlecloud: unable to read Service Account file: %v", err)
|
||||
func NewDNSProviderServiceAccountKey(saKey []byte) (*DNSProvider, error) {
|
||||
if len(saKey) == 0 {
|
||||
return nil, fmt.Errorf("googlecloud: Service Account is missing")
|
||||
}
|
||||
|
||||
// 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 {
|
||||
ProjectID string `json:"project_id"`
|
||||
}
|
||||
err = json.Unmarshal(dat, &datJSON)
|
||||
err := json.Unmarshal(saKey, &datJSON)
|
||||
if err != nil || datJSON.ProjectID == "" {
|
||||
return nil, fmt.Errorf("googlecloud: project ID not found in Google Cloud Service Account file")
|
||||
}
|
||||
project = datJSON.ProjectID
|
||||
}
|
||||
|
||||
conf, err := google.JWTConfigFromJSON(dat, dns.NdevClouddnsReadwriteScope)
|
||||
conf, err := google.JWTConfigFromJSON(saKey, dns.NdevClouddnsReadwriteScope)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("googlecloud: unable to acquire config: %v", err)
|
||||
}
|
||||
|
@ -124,6 +119,21 @@ func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) {
|
|||
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.
|
||||
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||
if config == nil {
|
||||
|
|
|
@ -19,7 +19,8 @@ import (
|
|||
var envTest = tester.NewEnvTest(
|
||||
"GCE_PROJECT",
|
||||
"GCE_SERVICE_ACCOUNT_FILE",
|
||||
"GOOGLE_APPLICATION_CREDENTIALS").
|
||||
"GOOGLE_APPLICATION_CREDENTIALS",
|
||||
"GCE_SERVICE_ACCOUNT").
|
||||
WithDomain("GCE_DOMAIN").
|
||||
WithLiveTestExtra(func() bool {
|
||||
_, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope)
|
||||
|
@ -51,12 +52,19 @@ func TestNewDNSProvider(t *testing.T) {
|
|||
expected: "googlecloud: project name missing",
|
||||
},
|
||||
{
|
||||
desc: "success",
|
||||
desc: "success key file",
|
||||
envVars: map[string]string{
|
||||
"GCE_PROJECT": "",
|
||||
"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 {
|
||||
|
|
Loading…
Reference in a new issue