mirror of
				https://github.com/go-acme/lego.git
				synced 2025-10-31 16:37:41 +02:00 
			
		
		
		
	alidns: support ECS instance RAM role (#1462)
This commit is contained in:
		| @@ -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) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user