-
Notifications
You must be signed in to change notification settings - Fork 10
/
export_gs_iam.go
91 lines (85 loc) · 2.48 KB
/
export_gs_iam.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
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
)
// ExportStorageIAMPolicy prints a migration that sets IAM for each bucket owned by the project.
func ExportStorageIAMPolicy(cfg Config) error {
// get all buckets
cmdline := []string{"gsutil", "list"}
if cfg.verbose {
log.Println(strings.Join(cmdline, " "))
}
out := new(bytes.Buffer)
cmd := exec.Command(cmdline[0], cmdline[1:]...)
cmd.Stdout = out
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
buckets := strings.Split(strings.TrimSpace(string(out.Bytes())), "\n")
// build data structure for migration
type memberRolesPerBucket struct {
bucket string
memberToRoles map[string][]string
}
list := []memberRolesPerBucket{}
for _, each := range buckets {
policy, err := fetchIAMPolicy([]string{"gsutil", "iam", "get", each}, cfg.verbose)
if err != nil {
return err
}
list = append(list, memberRolesPerBucket{
bucket: each,
memberToRoles: policy.buildMemberToRoles(),
})
}
// begin writing migration
content := new(bytes.Buffer)
fmt.Fprintln(content, "# exported buckets iam policy")
fmt.Fprint(content, "\ndo:")
for _, each := range list {
fmt.Fprintf(content, "\n # bucket = %s\n", each.bucket)
if len(each.memberToRoles) == 3 { // projectViewer,Editor,Owner // skip defaults
continue
}
for member, roles := range each.memberToRoles {
if strings.HasPrefix(member, "project") { // skip defaults
continue
}
fmt.Fprintf(content, "\n # member = %s\n", member)
for _, role := range roles {
shortRole := strings.TrimPrefix(role, "roles/storage.")
cmd := fmt.Sprintf(" - gsutil iam ch %s:%s %s\n", member, shortRole, each.bucket)
fmt.Fprintf(content, cmd)
}
}
}
// UNDO section
fmt.Fprint(content, "\nundo:")
for _, each := range list {
fmt.Fprintf(content, "\n # bucket = %s\n", each.bucket)
for member, roles := range each.memberToRoles {
if strings.HasPrefix(member, "project") { // skip defaults
continue
}
fmt.Fprintf(content, "\n # member = %s\n", member)
for _, role := range roles {
shortRole := strings.TrimPrefix(role, "roles/storage.")
cmd := fmt.Sprintf(" - gsutil iam ch -d %s:%s %s\n", member, shortRole, each.bucket)
fmt.Fprintf(content, cmd)
}
}
}
// write the migration
filename := NewFilenameWithIndex("exported buckets iam policy")
if cfg.verbose {
log.Println("writing", filename)
}
return ioutil.WriteFile(filename, content.Bytes(), os.ModePerm)
}