Skip to content

Commit 1dd027b

Browse files
committed
mantle: overhaul aliyun auth
The Aliyun SDK has a native file format it can consume for credentials [1]. This commit proposes we use that file format here and drop the custom JSON parsing that we're doing for Aliyun. This commit also drops the toplevel `--config` argument in `cmd-ore-wrapper` because Aliyun was the only consumer of that argument. [1] https://github.com/aliyun/alibaba-cloud-sdk-go/blob/710fea6cf27cf855f301462a2adcf3399169f63c/docs/2-Client-EN.md#2-credentials-file
1 parent 0cb63a8 commit 1dd027b

File tree

6 files changed

+74
-142
lines changed

6 files changed

+74
-142
lines changed

docs/mantle/credentials.md

+26-35
Original file line numberDiff line numberDiff line change
@@ -19,45 +19,36 @@ kola spawn -p aws --aws-profile other_profile
1919

2020
## aliyun
2121

22-
`aliyun` reads the `~/.aliyun/config.json` file used by Aliyun's aliyun command-line tool.
23-
It can be created using the `aliyun` command:
24-
```
25-
$ aliyun configure
26-
```
27-
To configure a different profile, use the `--profile` flag
28-
```
29-
$ aliyun configure --profile other_profile
30-
```
22+
The Access Key/Secret for the Aliyun SDK can be specified either
23+
in a [credentials file](https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md#2-credentials-file)
24+
or directly in [environment variables](https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md#1-environment-credentials)
25+
as authentication input.
26+
27+
- credentials file
28+
- place the file in `~/.alibabacloud/credentials`
29+
- populate the `ALIBABA_CLOUD_CREDENTIALS_FILE` environment variable
30+
with the path to the credentials file.
31+
- environment variables
32+
- populate the key in the `ALIBABA_CLOUD_ACCESS_KEY_ID` environment variable
33+
- populate the secret in the `ALIBABA_CLOUD_ACCESS_KEY_SECRET` environment variable
34+
35+
Ironically, the `aliyun` CLI uses the slightly different
36+
[environment variables](https://github.com/aliyun/aliyun-cli#support-for-environment-variables)
37+
of `ALIBABACLOUD_ACCESS_KEY_ID` and `ALIBABACLOUD_ACCESS_KEY_SECRET`.
38+
39+
40+
For mantle populate the credentials file and either place it at `~/.alibabacloud/credentials`
41+
or populate the `ALIBABA_CLOUD_CREDENTIALS_FILE` environment variable.
3142

32-
The `~/.aliyun/config.json` file can also be populated manually:
3343
```
34-
{
35-
"current": "",
36-
"profiles": [
37-
{
38-
"name": "",
39-
"mode": "AK",
40-
"access_key_id": "ACCESS_KEY_ID",
41-
"access_key_secret": "ACCESS_KEY_SECRET",
42-
"sts_token": "",
43-
"ram_role_name": "",
44-
"ram_role_arn": "",
45-
"ram_session_name": "",
46-
"private_key": "",
47-
"key_pair_name": "",
48-
"expired_seconds": 0,
49-
"verified": "",
50-
"region_id": "eu-central-1",
51-
"output_format": "json",
52-
"language": "zh",
53-
"site": "",
54-
"retry_timeout": 0,
55-
"retry_count": 0
56-
}
57-
]
58-
}
44+
[default]
45+
type=access_key
46+
access_key_id=ACCESS_KEY_ID
47+
access_key_secret=ACCESS_KEY_SECRET
5948
```
6049

50+
To configure a different profile than `default`, use the `--profile` flag.
51+
6152
## aws
6253

6354
`aws` reads the `~/.aws/credentials` file used by Amazon's aws command-line tool.

mantle/auth/aliyun.go

-70
This file was deleted.

mantle/cmd/ore/aliyun/aliyun.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package aliyun
1616

1717
import (
1818
"fmt"
19-
"os"
2019

2120
"github.com/coreos/pkg/capnslog"
2221
"github.com/spf13/cobra"
@@ -38,9 +37,7 @@ var (
3837
)
3938

4039
func init() {
41-
defaultConfigPath := os.Getenv("ALIYUN_CONFIG_FILE")
42-
43-
Aliyun.PersistentFlags().StringVar(&options.ConfigPath, "config-file", defaultConfigPath, "config file (default \""+defaultConfigPath+"\")")
40+
Aliyun.PersistentFlags().StringVar(&options.CredentialsFile, "credentials-file", "", "Use custom path for Aliyun credentials file")
4441
Aliyun.PersistentFlags().StringVar(&options.Profile, "profile", "", "profile (default \"default\")")
4542
Aliyun.PersistentFlags().StringVar(&options.Region, "region", "", "region")
4643
cli.WrapPreRun(Aliyun, preflightCheck)

mantle/platform/api/aliyun/api.go

+40-25
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ package aliyun
1717
import (
1818
"fmt"
1919
"io"
20+
"os"
2021
"sort"
2122
"time"
2223

23-
"github.com/coreos/mantle/auth"
2424
"github.com/coreos/mantle/platform"
2525
"github.com/coreos/mantle/util"
2626
"github.com/coreos/pkg/capnslog"
2727
"github.com/coreos/pkg/multierror"
2828

29+
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
30+
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider"
2931
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
3032
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
3133
"github.com/aliyun/aliyun-oss-go-sdk/oss"
@@ -41,8 +43,11 @@ type Options struct {
4143
// The aliyun region regional api calls should use
4244
Region string
4345

44-
// Config file. Defaults to ~/.aliyun/config.json
45-
ConfigPath string
46+
47+
// Path to an ALIBABA_CLOUD_CREDENTIALS_FILE
48+
// https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md#2-credentials-file
49+
CredentialsFile string
50+
4651
// The profile to use when resolving credentials, if applicable
4752
Profile string
4853

@@ -62,30 +67,40 @@ type API struct {
6267
// standard credentials sources, including the environment and the profile
6368
// configured in ~/.aliyun.
6469
func New(opts *Options) (*API, error) {
65-
profiles, err := auth.ReadAliyunConfig(opts.ConfigPath)
66-
if err != nil {
67-
return nil, fmt.Errorf("couldn't read aliyun config: %v", err)
68-
}
6970

70-
if opts.Profile == "" {
71-
opts.Profile = "default"
72-
}
73-
74-
profile, ok := profiles[opts.Profile]
75-
if !ok {
76-
return nil, fmt.Errorf("no such profile %q", opts.Profile)
77-
}
78-
79-
if opts.AccessKeyID == "" {
80-
opts.AccessKeyID = profile.AccessKeyID
81-
}
82-
83-
if opts.SecretKey == "" {
84-
opts.SecretKey = profile.AccessKeySecret
85-
}
71+
// If the user didn't provide an access key and secret directly then try to pick up
72+
// the credentials from the normal locations defined by the SDK
73+
// https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md#default-credential-provider-chain
74+
if opts.AccessKeyID == "" || opts.SecretKey == "" {
75+
76+
// If the user provided a path to a credential file then
77+
// let's set it now the only supported way, which is with
78+
// the ALIBABA_CLOUD_CREDENTIALS_FILE env var.
79+
if opts.CredentialsFile != "" {
80+
os.Setenv(provider.ENVCredentialFile, opts.CredentialsFile)
81+
defer os.Unsetenv(provider.ENVCredentialFile)
82+
}
8683

87-
if opts.Region == "" {
88-
opts.Region = profile.Region
84+
var p provider.Provider
85+
if opts.Profile != "" {
86+
// If the user specified a profile then they're
87+
// using a credentials file with profiles in them.
88+
p = provider.NewProfileProvider(opts.Profile)
89+
} else {
90+
// If not then they could be using environment variables
91+
// so use the DefaultChain (includes env var provider)
92+
p = provider.DefaultChain
93+
}
94+
credential, err := p.Resolve()
95+
if err != nil {
96+
return nil, fmt.Errorf("failed to detect aliyun auth credentials: %w", err)
97+
}
98+
keycred, ok := credential.(*credentials.AccessKeyCredential)
99+
if !ok {
100+
return nil, fmt.Errorf("failed to convert the credential to an AccessKeyCredential")
101+
}
102+
opts.AccessKeyID = keycred.AccessKeyId
103+
opts.SecretKey = keycred.AccessKeySecret
89104
}
90105

91106
ecs, err := ecs.NewClientWithAccessKey(opts.Region, opts.AccessKeyID, opts.SecretKey)

src/cmd-ore-wrapper

-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ Each target has its own sub options. To access them us:
7272
parser.add_argument("--build-artifact", "--build-if-missing",
7373
action='store_true', default=default_build_artifact,
7474
help="Build the artifact if missing")
75-
parser.add_argument("--config", "--config-file",
76-
help="ore configuration")
7775
parser.add_argument("--force", action='store_true',
7876
help="Force the operation if it has already happened")
7977
parser.add_argument("--compress", action='store_true',

src/cosalib/aliyun.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def aliyun_run_ore_replicate(build, args):
3131

3232
if not args.region:
3333
args.region = subprocess.check_output([
34-
'ore', f'--config-file={args.config}' if args.config else '',
34+
'ore', f'--credentials-file={args.credentials_file}' if args.credentials_file else '',
3535
'aliyun', 'list-regions'
3636
]).decode().strip().split()
3737
log.info(("default: replicating to all regions. If this is not "
@@ -65,8 +65,8 @@ def aliyun_run_ore_replicate(build, args):
6565
'--wait-for-ready'
6666
]
6767

68-
if args.config:
69-
ore_args.extend(['--config-file', args.config])
68+
if args.credentials_file:
69+
ore_args.extend(['--credentials-file', args.credentials_file])
7070

7171
upload_failed_in_region = None
7272

@@ -115,8 +115,8 @@ def make_public(build, args):
115115
'aliyun', 'visibility', '--public'
116116
]
117117

118-
if args.config:
119-
make_public_args.extend(['--config-file', args.config])
118+
if args.credentials_file:
119+
make_public_args.extend(['--credentials-file', args.credentials_file])
120120

121121
# build out a list of region:image pairs to pass to `ore aliyun visibility`
122122
region_image_pairs = []
@@ -157,7 +157,7 @@ def aliyun_run_ore(build, args):
157157
raise Exception("Must supply OSS bucket when uploading")
158158

159159
ore_args.extend([
160-
f'--config-file={args.config}' if args.config else '',
160+
f'--credentails-file={args.credentials_file}' if args.credentials_file else '',
161161
'aliyun', 'create-image',
162162
'--region', region,
163163
'--bucket', args.bucket,
@@ -187,6 +187,7 @@ def aliyun_run_ore(build, args):
187187

188188
def aliyun_cli(parser):
189189
parser.add_argument("--bucket", help="OSS Bucket")
190+
parser.add_argument("--credentials-file", help="Credentials file to use")
190191
parser.add_argument("--name-suffix", help="Suffix for uploaded image name")
191192
parser.add_argument("--public", action="store_true", help="Mark images as publicly available")
192193
return parser

0 commit comments

Comments
 (0)