Skip to content

Commit 3d3cad9

Browse files
night556JacksonTian
authored andcommitted
add external mode
1 parent c486e4c commit 3d3cad9

File tree

9 files changed

+107
-4
lines changed

9 files changed

+107
-4
lines changed

config/configure.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
package config
1515

1616
import (
17+
"bufio"
1718
"fmt"
1819
"io"
1920
"io/ioutil"
21+
"os"
2022
"strconv"
2123
"strings"
2224

@@ -107,6 +109,9 @@ func doConfigure(ctx *cli.Context, profileName string, mode string) error {
107109
case RsaKeyPair:
108110
cp.Mode = RsaKeyPair
109111
configureRsaKeyPair(w, &cp)
112+
case External:
113+
cp.Mode = External
114+
configureExternal(w, &cp)
110115
default:
111116
return fmt.Errorf("unexcepted authenticate mode: %s", mode)
112117
}
@@ -218,9 +223,18 @@ func configureRsaKeyPair(w io.Writer, cp *Profile) error {
218223
return nil
219224
}
220225

226+
func configureExternal(w io.Writer, cp *Profile) error {
227+
cli.Printf(w, "Process Command [%s]: ", cp.ProcessCommand)
228+
cp.ProcessCommand = ReadInput(cp.ProcessCommand)
229+
return nil
230+
}
231+
221232
func ReadInput(defaultValue string) string {
222233
var s string
223-
fmt.Scanf("%s\n", &s)
234+
scanner := bufio.NewScanner(os.Stdin)
235+
if scanner.Scan() {
236+
s = scanner.Text()
237+
}
224238
if s == "" {
225239
return defaultValue
226240
}

config/configure_get_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func TestDoConfigureGet(t *testing.T) {
7979
ctx.Flags().Get("profile").SetAssigned(true)
8080
ctx.Flags().Get("profile").SetValue("default")
8181
doConfigureGet(ctx, []string{})
82-
assert.Equal(t, "{\n\t\"name\": \"default\",\n\t\"mode\": \"AK\",\n\t\"access_key_id\": \"default_aliyun_access_key_id\",\n\t\"access_key_secret\": \"default_aliyun_access_key_secret\",\n\t\"sts_token\": \"\",\n\t\"ram_role_name\": \"\",\n\t\"ram_role_arn\": \"\",\n\t\"ram_session_name\": \"\",\n\t\"private_key\": \"\",\n\t\"key_pair_name\": \"\",\n\t\"expired_seconds\": 0,\n\t\"verified\": \"\",\n\t\"region_id\": \"\",\n\t\"output_format\": \"json\",\n\t\"language\": \"\",\n\t\"site\": \"\",\n\t\"retry_timeout\": 0,\n\t\"connect_timeout\": 0,\n\t\"retry_count\": 0\n}\n\n", w.String())
82+
assert.Equal(t, "{\n\t\"name\": \"default\",\n\t\"mode\": \"AK\",\n\t\"access_key_id\": \"default_aliyun_access_key_id\",\n\t\"access_key_secret\": \"default_aliyun_access_key_secret\",\n\t\"sts_token\": \"\",\n\t\"ram_role_name\": \"\",\n\t\"ram_role_arn\": \"\",\n\t\"ram_session_name\": \"\",\n\t\"private_key\": \"\",\n\t\"key_pair_name\": \"\",\n\t\"expired_seconds\": 0,\n\t\"verified\": \"\",\n\t\"region_id\": \"\",\n\t\"output_format\": \"json\",\n\t\"language\": \"\",\n\t\"site\": \"\",\n\t\"retry_timeout\": 0,\n\t\"connect_timeout\": 0,\n\t\"retry_count\": 0,\n\t\"process_command\": \"\"\n}\n\n", w.String())
8383

8484
//testcase 5
8585
hookLoadConfiguration = func(fn func(path string, w io.Writer) (Configuration, error)) func(path string, w io.Writer) (Configuration, error) {

config/configure_list.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ func doConfigureList(w io.Writer) {
6767
cred = "arn:" + "***" + GetLastChars(pf.AccessKeyId, 3)
6868
case RsaKeyPair:
6969
cred = "RsaKeyPair:" + pf.KeyPairName
70+
case External:
71+
cred = "ProcessCommand:" + pf.ProcessCommand
7072
}
7173
fmt.Fprintf(tw, "%s\t| %s\t| %s\t| %s\t| %s\n", name, cred, valid, pf.RegionId, pf.Language)
7274
}

config/configure_set.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ func doConfigureSet(w io.Writer, flags *cli.FlagSet) {
111111
case RsaKeyPair:
112112
profile.PrivateKey = PrivateKeyFlag(flags).GetStringOrDefault(profile.PrivateKey)
113113
profile.KeyPairName = KeyPairNameFlag(flags).GetStringOrDefault(profile.KeyPairName)
114+
case External:
115+
profile.ProcessCommand = ProcessCommandFlag(flags).GetStringOrDefault(profile.ProcessCommand)
114116
}
115117
profile.RegionId = RegionFlag(flags).GetStringOrDefault(profile.RegionId)
116118
profile.Language = LanguageFlag(flags).GetStringOrDefault(profile.Language)

config/configure_set_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func TestDoConfigureSet(t *testing.T) {
108108
w.Reset()
109109
doConfigureSet(w, fs)
110110
assert.Empty(t, w.String())
111-
111+
112112
//RsaKeyPair
113113
hookLoadConfiguration = func(fn func(path string, w io.Writer) (Configuration, error)) func(path string, w io.Writer) (Configuration, error) {
114114
return func(path string, w io.Writer) (Configuration, error) {
@@ -118,4 +118,14 @@ func TestDoConfigureSet(t *testing.T) {
118118
w.Reset()
119119
doConfigureSet(w, fs)
120120
assert.Empty(t, w.String())
121+
122+
//External
123+
hookLoadConfiguration = func(fn func(path string, w io.Writer) (Configuration, error)) func(path string, w io.Writer) (Configuration, error) {
124+
return func(path string, w io.Writer) (Configuration, error) {
125+
return Configuration{CurrentProfile: "default", Profiles: []Profile{Profile{Name: "default", Mode: External, ProcessCommand: "process command", OutputFormat: "json", RegionId: "cn-hangzhou"}, Profile{Name: "aaa", Mode: AK, AccessKeyId: "sdf", AccessKeySecret: "ddf", OutputFormat: "json"}}}, nil
126+
}
127+
}
128+
w.Reset()
129+
doConfigureSet(w, fs)
130+
assert.Empty(t, w.String())
121131
}

config/configure_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ func TestConfigureRsaKeyPair(t *testing.T) {
179179
assert.EqualError(t, err, "read key file failed open : no such file or directory")
180180
}
181181
}
182+
183+
func TestConfigureExternal(t *testing.T) {
184+
w := new(bytes.Buffer)
185+
err := configureExternal(w, &Profile{Name: "default", Mode: External, ProcessCommand: "process command", RegionId: "cn-hangzhou", OutputFormat: "json"})
186+
assert.Equal(t, "Process Command [process command]: ", w.String())
187+
assert.Nil(t, err)
188+
}
189+
182190
func TestReadInput(t *testing.T) {
183191
assert.Equal(t, "default", ReadInput("default"))
184192
}

config/flags.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const (
3737
SkipSecureVerifyName = "skip-secure-verify"
3838
ConfigurePathFlagName = "config-path"
3939
ExpiredSecondsFlagName = "expired-seconds"
40+
ProcessCommandFlagName = "process-command"
4041
)
4142

4243
func AddFlags(fs *cli.FlagSet) {
@@ -58,6 +59,7 @@ func AddFlags(fs *cli.FlagSet) {
5859
fs.Add(NewRetryCountFlag())
5960
fs.Add(NewSkipSecureVerify())
6061
fs.Add(NewExpiredSecondsFlag())
62+
fs.Add(NewProcessCommandFlag())
6163
}
6264
func ConnectTimeoutFlag(fs *cli.FlagSet) *cli.Flag {
6365
return fs.Get(ConnectTimeoutFlagName)
@@ -128,6 +130,9 @@ func ConfigurePathFlag(fs *cli.FlagSet) *cli.Flag {
128130
func ExpiredSecondsFlag(fs *cli.FlagSet) *cli.Flag {
129131
return fs.Get(ExpiredSecondsFlagName)
130132
}
133+
func ProcessCommandFlag(fs *cli.FlagSet) *cli.Flag {
134+
return fs.Get(ProcessCommandFlagName)
135+
}
131136

132137
//var OutputFlag = &cli.Flag{Category: "config",
133138
// Name: "output", AssignedMode: cli.AssignedOnce, Hidden: true,
@@ -244,6 +249,18 @@ func NewKeyPairNameFlag() *cli.Flag {
244249
"使用 `--key-pair-name <KeyPairName>` 指定KeyPairName")}
245250
}
246251

252+
func NewProcessCommandFlag() *cli.Flag {
253+
return &cli.Flag{
254+
Category: "config",
255+
Name: ProcessCommandFlagName,
256+
AssignedMode: cli.AssignedOnce,
257+
Short: i18n.T(
258+
"use `--process-command <ProcessCommand>` to specify external program execution command",
259+
"使用 `--process-command <ProcessCommand>` 指定外部程序运行命令",
260+
),
261+
}
262+
}
263+
247264
func NewRegionFlag() *cli.Flag {
248265
return &cli.Flag{Category: "config",
249266
Name: RegionFlagName,

config/flags_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,25 @@ func TestAddFlag(t *testing.T) {
204204
DefaultValue: "",
205205
Persistent: false,
206206
}
207+
newProcessCommandFlag = &cli.Flag{
208+
Category: "config",
209+
Name: ProcessCommandFlagName,
210+
AssignedMode: cli.AssignedOnce,
211+
Short: i18n.T(
212+
"use `--process-command <ProcessCommand>` to specify external program execution command",
213+
"使用 `--process-command <ProcessCommand>` 指定外部程序运行命令",
214+
),
215+
Long: nil,
216+
Required: false,
217+
Aliases: nil,
218+
Hidden: false,
219+
Validate: nil,
220+
Fields: nil,
221+
ExcludeWith: nil,
222+
Shorthand: 0,
223+
DefaultValue: "",
224+
Persistent: false,
225+
}
207226
newRegionFlag = &cli.Flag{
208227
Category: "config",
209228
Name: RegionFlagName,
@@ -365,6 +384,9 @@ func TestAddFlag(t *testing.T) {
365384
f = NewKeyPairNameFlag()
366385
assert.Equal(t, newKeyPairNameFlag, f)
367386

387+
f = NewProcessCommandFlag()
388+
assert.Equal(t, newProcessCommandFlag, f)
389+
368390
f = NewRegionFlag()
369391
assert.Equal(t, newRegionFlag, f)
370392

config/profile.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ import (
1818
"errors"
1919
"fmt"
2020
"os"
21+
"os/exec"
2122
"regexp"
2223
"strconv"
24+
"strings"
2325
"time"
2426

2527
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
@@ -39,6 +41,7 @@ const (
3941
EcsRamRole = AuthenticateMode("EcsRamRole")
4042
RsaKeyPair = AuthenticateMode("RsaKeyPair")
4143
RamRoleArnWithEcs = AuthenticateMode("RamRoleArnWithRoleName")
44+
External = AuthenticateMode("External")
4245
)
4346

4447
type Profile struct {
@@ -61,6 +64,7 @@ type Profile struct {
6164
ReadTimeout int `json:"retry_timeout"`
6265
ConnectTimeout int `json:"connect_timeout"`
6366
RetryCount int `json:"retry_count"`
67+
ProcessCommand string `json:"process_command"`
6468
parent *Configuration //`json:"-"`
6569
}
6670

@@ -117,10 +121,13 @@ func (cp *Profile) Validate() error {
117121
if cp.KeyPairName == "" {
118122
return fmt.Errorf("invailed key_pair_name")
119123
}
124+
case External:
125+
if cp.ProcessCommand == "" {
126+
return fmt.Errorf("invailed process_command")
127+
}
120128
default:
121129
return fmt.Errorf("invailed mode: %s", cp.Mode)
122130
}
123-
124131
return nil
125132
}
126133

@@ -144,6 +151,7 @@ func (cp *Profile) OverwriteWithFlags(ctx *cli.Context) {
144151
cp.ConnectTimeout = ConnectTimeoutFlag(ctx.Flags()).GetIntegerOrDefault(cp.ConnectTimeout)
145152
cp.RetryCount = RetryCountFlag(ctx.Flags()).GetIntegerOrDefault(cp.RetryCount)
146153
cp.ExpiredSeconds = ExpiredSecondsFlag(ctx.Flags()).GetIntegerOrDefault(cp.ExpiredSeconds)
154+
cp.ProcessCommand = ProcessCommandFlag(ctx.Flags()).GetStringOrDefault(cp.ProcessCommand)
147155

148156
if cp.AccessKeyId == "" {
149157
switch {
@@ -199,6 +207,8 @@ func AutoModeRecognition(cp *Profile) {
199207
cp.Mode = RsaKeyPair
200208
} else if cp.RamRoleName != "" {
201209
cp.Mode = EcsRamRole
210+
} else if cp.ProcessCommand != "" {
211+
cp.Mode = External
202212
}
203213
}
204214

@@ -233,6 +243,8 @@ func (cp *Profile) GetClient(ctx *cli.Context) (*sdk.Client, error) {
233243
client, err = cp.GetClientByPrivateKey(config)
234244
case RamRoleArnWithEcs:
235245
client, err = cp.GetClientByRamRoleArnWithEcs(config)
246+
case External:
247+
return cp.GetClientByExternal(config, ctx)
236248
default:
237249
client, err = nil, fmt.Errorf("unexcepted certificate mode: %s", cp.Mode)
238250
}
@@ -336,6 +348,22 @@ func (cp *Profile) GetClientByPrivateKey(config *sdk.Config) (*sdk.Client, error
336348
return client, err
337349
}
338350

351+
func (cp *Profile) GetClientByExternal(config *sdk.Config, ctx *cli.Context) (*sdk.Client, error) {
352+
args := strings.Fields(cp.ProcessCommand)
353+
cmd := exec.Command(args[0], args[1:]...)
354+
buf, err := cmd.CombinedOutput()
355+
if err != nil {
356+
return nil, err
357+
}
358+
err = json.Unmarshal(buf, cp)
359+
if err != nil {
360+
fmt.Println(cp.ProcessCommand)
361+
fmt.Println(string(buf))
362+
return nil, err
363+
}
364+
return cp.GetClient(ctx)
365+
}
366+
339367
func IsRegion(region string) bool {
340368
if match, _ := regexp.MatchString("^[a-zA-Z0-9-]*$", region); !match {
341369
return false

0 commit comments

Comments
 (0)