alidns: support ECS instance RAM role (#1462)

This commit is contained in:
Yuanhai He 2021-08-25 18:49:56 +08:00 committed by GitHub
parent dc2b19e1b1
commit 99ba43f743
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 19 deletions

View file

@ -142,6 +142,7 @@ func displayDNSHelp(name string) error {
ew.writeln(`Credentials:`)
ew.writeln(` - "ALICLOUD_ACCESS_KEY": Access key ID`)
ew.writeln(` - "ALICLOUD_RAM_ROLE": Your instance RAM role (https://www.alibabacloud.com/help/doc-detail/54579.htm)`)
ew.writeln(` - "ALICLOUD_SECRET_KEY": Access Key secret`)
ew.writeln(` - "ALICLOUD_SECURITY_TOKEN": STS Security Token (optional)`)
ew.writeln()

View file

@ -21,8 +21,14 @@ Configuration for [Alibaba Cloud DNS](https://www.alibabacloud.com/product/dns).
Here is an example bash command using the Alibaba Cloud DNS provider:
```bash
# Setup using instance RAM role
ALICLOUD_RAM_ROLE=lego \
lego --email myemail@example.com --dns alidns --domains my.example.org run
# Or, using credentials
ALICLOUD_ACCESS_KEY=abcdefghijklmnopqrstuvwx \
ALICLOUD_SECRET_KEY=xxxxxxx \
ALICLOUD_SECRET_KEY=your-secret-key \
ALICLOUD_SECURITY_TOKEN=your-sts-token \
lego --email myemail@example.com --dns alidns --domains my.example.org run
```
@ -34,6 +40,7 @@ lego --email myemail@example.com --dns alidns --domains my.example.org run
| Environment Variable Name | Description |
|-----------------------|-------------|
| `ALICLOUD_ACCESS_KEY` | Access key ID |
| `ALICLOUD_RAM_ROLE` | Your instance RAM role (https://www.alibabacloud.com/help/doc-detail/54579.htm) |
| `ALICLOUD_SECRET_KEY` | Access Key secret |
| `ALICLOUD_SECURITY_TOKEN` | STS Security Token (optional) |

View file

@ -23,6 +23,7 @@ const defaultRegionID = "cn-hangzhou"
const (
envNamespace = "ALICLOUD_"
EnvRAMRole = envNamespace + "RAM_ROLE"
EnvAccessKey = envNamespace + "ACCESS_KEY"
EnvSecretKey = envNamespace + "SECRET_KEY"
EnvSecurityToken = envNamespace + "SECURITY_TOKEN"
@ -36,6 +37,7 @@ const (
// Config is used to configure the creation of the DNSProvider.
type Config struct {
RAMRole string
APIKey string
SecretKey string
SecurityToken string
@ -63,18 +65,26 @@ type DNSProvider struct {
}
// NewDNSProvider returns a DNSProvider instance configured for Alibaba Cloud DNS.
// Credentials must be passed in the environment variables:
// - If you're using the instance RAM role, the RAM role environment variable must be passed in: ALICLOUD_RAM_ROLE.
// - Other than that, credentials must be passed in the environment variables:
// ALICLOUD_ACCESS_KEY, ALICLOUD_SECRET_KEY, and optionally ALICLOUD_SECURITY_TOKEN.
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvAccessKey, EnvSecretKey)
config := NewDefaultConfig()
config.RegionID = env.GetOrFile(EnvRegionID)
values, err := env.Get(EnvRAMRole)
if err == nil {
config.RAMRole = values[EnvRAMRole]
return NewDNSProviderConfig(config)
}
values, err = env.Get(EnvAccessKey, EnvSecretKey)
if err != nil {
return nil, fmt.Errorf("alicloud: %w", err)
}
config := NewDefaultConfig()
config.APIKey = values[EnvAccessKey]
config.SecretKey = values[EnvSecretKey]
config.RegionID = env.GetOrFile(EnvRegionID)
config.SecurityToken = env.GetOrFile(EnvSecurityToken)
return NewDNSProviderConfig(config)
@ -86,23 +96,24 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return nil, errors.New("alicloud: the configuration of the DNS provider is nil")
}
if config.APIKey == "" || config.SecretKey == "" {
return nil, fmt.Errorf("alicloud: credentials missing")
}
if config.RegionID == "" {
config.RegionID = defaultRegionID
}
conf := sdk.NewConfig().WithTimeout(config.HTTPTimeout)
var credential auth.Credential
if config.SecurityToken == "" {
credential = credentials.NewAccessKeyCredential(config.APIKey, config.SecretKey)
} else {
switch {
case config.RAMRole != "":
credential = credentials.NewEcsRamRoleCredential(config.RAMRole)
case config.APIKey != "" && config.SecretKey != "" && config.SecurityToken != "":
credential = credentials.NewStsTokenCredential(config.APIKey, config.SecretKey, config.SecurityToken)
case config.APIKey != "" && config.SecretKey != "":
credential = credentials.NewAccessKeyCredential(config.APIKey, config.SecretKey)
default:
return nil, fmt.Errorf("alicloud: ram role or credentials missing")
}
conf := sdk.NewConfig().WithTimeout(config.HTTPTimeout)
client, err := alidns.NewClientWithOptions(config.RegionID, conf, credential)
if err != nil {
return nil, fmt.Errorf("alicloud: credentials failed: %w", err)

View file

@ -5,13 +5,20 @@ Code = "alidns"
Since = "v1.1.0"
Example = '''
# Setup using instance RAM role
ALICLOUD_RAM_ROLE=lego \
lego --email myemail@example.com --dns alidns --domains my.example.org run
# Or, using credentials
ALICLOUD_ACCESS_KEY=abcdefghijklmnopqrstuvwx \
ALICLOUD_SECRET_KEY=xxxxxxx \
ALICLOUD_SECRET_KEY=your-secret-key \
ALICLOUD_SECURITY_TOKEN=your-sts-token \
lego --email myemail@example.com --dns alidns --domains my.example.org run
'''
[Configuration]
[Configuration.Credentials]
ALICLOUD_RAM_ROLE = "Your instance RAM role (https://www.alibabacloud.com/help/doc-detail/54579.htm)"
ALICLOUD_ACCESS_KEY = "Access key ID"
ALICLOUD_SECRET_KEY = "Access Key secret"
ALICLOUD_SECURITY_TOKEN = "STS Security Token (optional)"

View file

@ -12,7 +12,8 @@ const envDomain = envNamespace + "DOMAIN"
var envTest = tester.NewEnvTest(
EnvAccessKey,
EnvSecretKey).
EnvSecretKey,
EnvRAMRole).
WithDomain(envDomain)
func TestNewDNSProvider(t *testing.T) {
@ -28,6 +29,12 @@ func TestNewDNSProvider(t *testing.T) {
EnvSecretKey: "456",
},
},
{
desc: "success (RAM role)",
envVars: map[string]string{
EnvRAMRole: "LegoInstanceRole",
},
},
{
desc: "missing credentials",
envVars: map[string]string{
@ -78,6 +85,7 @@ func TestNewDNSProvider(t *testing.T) {
func TestNewDNSProviderConfig(t *testing.T) {
testCases := []struct {
desc string
ramRole string
apiKey string
secretKey string
expected string
@ -87,19 +95,23 @@ func TestNewDNSProviderConfig(t *testing.T) {
apiKey: "123",
secretKey: "456",
},
{
desc: "success",
ramRole: "LegoInstanceRole",
},
{
desc: "missing credentials",
expected: "alicloud: credentials missing",
expected: "alicloud: ram role or credentials missing",
},
{
desc: "missing api key",
secretKey: "456",
expected: "alicloud: credentials missing",
expected: "alicloud: ram role or credentials missing",
},
{
desc: "missing secret key",
apiKey: "123",
expected: "alicloud: credentials missing",
expected: "alicloud: ram role or credentials missing",
},
}
@ -108,6 +120,7 @@ func TestNewDNSProviderConfig(t *testing.T) {
config := NewDefaultConfig()
config.APIKey = test.apiKey
config.SecretKey = test.secretKey
config.RAMRole = test.ramRole
p, err := NewDNSProviderConfig(config)