forked from 99designs/aws-vault
/
rotate.go
114 lines (92 loc) · 2.95 KB
/
rotate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"github.com/99designs/aws-vault/keyring"
"github.com/99designs/aws-vault/prompt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/iam"
)
type RotateCommandInput struct {
Profile string
Keyring keyring.Keyring
MfaToken string
MfaPrompt prompt.PromptFunc
}
func RotateCommand(ui Ui, input RotateCommandInput) {
var err error
provider := &KeyringProvider{Keyring: input.Keyring, Profile: input.Profile}
oldMasterCreds, err := provider.Retrieve()
if err != nil {
ui.Error.Fatal(err)
}
ui.Debug.Println("Found old access key")
oldSessionCreds, err := NewVaultCredentials(input.Keyring, input.Profile, VaultOptions{
MfaToken: input.MfaToken,
MfaPrompt: input.MfaPrompt,
})
if err != nil {
ui.Error.Fatal(err)
}
ui.Debug.Println("Using old credentials to create a new access key")
oldVal, err := oldSessionCreds.Get()
if err != nil {
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" {
ui.Error.Fatalf("No credentials found for profile %q", input.Profile)
} else {
ui.Error.Fatal(err)
}
}
client := iam.New(session.New(&aws.Config{
Credentials: credentials.NewCredentials(&credentials.StaticProvider{Value: oldVal}),
}))
createOut, err := client.CreateAccessKey(&iam.CreateAccessKeyInput{})
if err != nil {
ui.Error.Fatal(err)
}
ui.Debug.Println("Created new access key")
newMasterCreds := credentials.Value{
AccessKeyID: *createOut.AccessKey.AccessKeyId,
SecretAccessKey: *createOut.AccessKey.SecretAccessKey,
}
if err := provider.Store(newMasterCreds); err != nil {
ui.Error.Println("Can't store new access key:", newMasterCreds)
ui.Error.Fatal(err)
}
sessions, err := NewKeyringSessions(input.Keyring)
if err != nil {
ui.Error.Fatal(err)
}
if n, _ := sessions.Delete(input.Profile); n > 0 {
ui.Debug.Printf("Deleted %d existing sessions.", n)
}
ui.Debug.Println("Using new credentials to delete the old new access key")
newSessionCreds, err := NewVaultCredentials(input.Keyring, input.Profile, VaultOptions{
MfaToken: input.MfaToken,
MfaPrompt: input.MfaPrompt,
})
if err != nil {
ui.Error.Fatal(err)
}
newVal, err := newSessionCreds.Get()
if err != nil {
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" {
ui.Error.Fatalf("No credentials found for profile %q", input.Profile)
} else {
ui.Error.Fatal(err)
}
}
client = iam.New(session.New(&aws.Config{
Credentials: credentials.NewCredentials(&credentials.StaticProvider{Value: newVal}),
}))
_, err = client.DeleteAccessKey(&iam.DeleteAccessKeyInput{
AccessKeyId: aws.String(oldMasterCreds.AccessKeyID),
})
if err != nil {
ui.Error.Println("Can't delete old access key:", oldMasterCreds)
ui.Error.Fatal(err)
}
ui.Printf("Rotated credentials for profile %q in vault", input.Profile)
ui.Exit(0)
}