forked from TrueCloudLab/lego
alidns: support ECS instance RAM role (#1462)
This commit is contained in:
parent
dc2b19e1b1
commit
99ba43f743
5 changed files with 58 additions and 19 deletions
|
@ -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()
|
||||
|
|
|
@ -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) |
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue