Konstantin Lebedev
4 years ago
2 changed files with 221 additions and 26 deletions
@ -0,0 +1,160 @@ |
|||||
|
package shell |
||||
|
|
||||
|
import ( |
||||
|
"flag" |
||||
|
"fmt" |
||||
|
"github.com/chrislusf/seaweedfs/weed/s3api" |
||||
|
"io" |
||||
|
"sort" |
||||
|
"strings" |
||||
|
|
||||
|
"github.com/chrislusf/seaweedfs/weed/filer" |
||||
|
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" |
||||
|
) |
||||
|
|
||||
|
func init() { |
||||
|
Commands = append(Commands, &commandS3Configure{}) |
||||
|
} |
||||
|
|
||||
|
type commandS3Configure struct { |
||||
|
} |
||||
|
|
||||
|
func (c *commandS3Configure) Name() string { |
||||
|
return "s3.configure" |
||||
|
} |
||||
|
|
||||
|
func (c *commandS3Configure) Help() string { |
||||
|
return `configure and apply s3 options for each bucket |
||||
|
# see the current configuration file content |
||||
|
s3.configure |
||||
|
` |
||||
|
} |
||||
|
|
||||
|
func (c *commandS3Configure) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) { |
||||
|
s3ConfigureCommand := flag.NewFlagSet(c.Name(), flag.ContinueOnError) |
||||
|
actions := s3ConfigureCommand.String("actions", "", "actions names") |
||||
|
user := s3ConfigureCommand.String("user", "", "user name") |
||||
|
buckets := s3ConfigureCommand.String("buckets", "", "bucket name") |
||||
|
accessKey := s3ConfigureCommand.String("access_key", "", "specify the access key") |
||||
|
secretKey := s3ConfigureCommand.String("secret_key", "", "specify the secret key") |
||||
|
isDelete := s3ConfigureCommand.Bool("delete", false, "delete users, actions or access keys") |
||||
|
apply := s3ConfigureCommand.Bool("apply", false, "update and apply s3 configuration") |
||||
|
|
||||
|
if err = s3ConfigureCommand.Parse(args); err != nil { |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
var identities []*s3api.Identity |
||||
|
if err = commandEnv.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { |
||||
|
request := &filer_pb.LookupDirectoryEntryRequest{ |
||||
|
Directory: filer.DirectoryEtc, |
||||
|
Name: s3api.S3ConfName, |
||||
|
} |
||||
|
respLookupEntry, err := filer_pb.LookupEntry(client, request) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
if err = s3api.LoadS3configFromEntryExtended(&respLookupEntry.Entry.Extended, &identities); err != nil { |
||||
|
return err |
||||
|
} |
||||
|
return nil |
||||
|
}); err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
idx := 0 |
||||
|
changed := false |
||||
|
if *user != "" && *buckets != "" { |
||||
|
for i, identity := range identities { |
||||
|
if *user == identity.Name { |
||||
|
idx = i |
||||
|
changed = true |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
cmdActions := []s3api.Action{} |
||||
|
for _, bucket := range strings.Split(*buckets, ",") { |
||||
|
for _, action := range strings.Split(*actions, ",") { |
||||
|
cmdActions = append(cmdActions, s3api.Action(fmt.Sprintf("%s:%s", action, bucket))) |
||||
|
} |
||||
|
} |
||||
|
cmdCredential := &s3api.Credential{ |
||||
|
AccessKey: *accessKey, |
||||
|
SecretKey: *secretKey, |
||||
|
} |
||||
|
|
||||
|
if changed { |
||||
|
if *isDelete { |
||||
|
exists := []int{} |
||||
|
for _, cmdAction := range cmdActions { |
||||
|
for i, currentAction := range identities[idx].Actions { |
||||
|
if cmdAction == currentAction { |
||||
|
exists = append(exists, i) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
sort.Sort(sort.Reverse(sort.IntSlice(exists))) |
||||
|
for _, i := range exists { |
||||
|
identities[idx].Actions = append(identities[idx].Actions[:i], identities[idx].Actions[i+1:]...) |
||||
|
} |
||||
|
if *accessKey != "" { |
||||
|
exists = []int{} |
||||
|
for i, credential := range identities[idx].Credentials { |
||||
|
if credential.AccessKey == *accessKey { |
||||
|
exists = append(exists, i) |
||||
|
} |
||||
|
} |
||||
|
sort.Sort(sort.Reverse(sort.IntSlice(exists))) |
||||
|
for _, i := range exists { |
||||
|
identities[idx].Credentials = append(identities[idx].Credentials[:i], identities[idx].Credentials[:i+1]...) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
if *actions == "" && *accessKey == "" { |
||||
|
identities = append(identities[:idx], identities[idx+1:]...) |
||||
|
} |
||||
|
} else { |
||||
|
identities[idx].Actions = append(identities[idx].Actions, cmdActions...) |
||||
|
identities[idx].Credentials = append(identities[idx].Credentials, &s3api.Credential{ |
||||
|
AccessKey: *accessKey, |
||||
|
SecretKey: *secretKey, |
||||
|
}) |
||||
|
} |
||||
|
} else { |
||||
|
identity := s3api.Identity{ |
||||
|
Name: *user, |
||||
|
Actions: cmdActions, |
||||
|
} |
||||
|
identity.Credentials = append(identity.Credentials, &s3api.Credential{ |
||||
|
AccessKey: *accessKey, |
||||
|
SecretKey: *secretKey, |
||||
|
}) |
||||
|
identities = append(identities, &identity) |
||||
|
} |
||||
|
|
||||
|
fmt.Fprintf(writer, fmt.Sprintf("%+v\n", identities)) |
||||
|
fmt.Fprintln(writer) |
||||
|
|
||||
|
if !*apply { |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
if err = commandEnv.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { |
||||
|
request := &filer_pb.LookupDirectoryEntryRequest{ |
||||
|
Directory: filer.DirectoryEtc, |
||||
|
Name: s3api.S3ConfName, |
||||
|
} |
||||
|
respLookupEntry, err := filer_pb.LookupEntry(client, request) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
if err = s3api.SaveS3configToEntryExtended(&respLookupEntry.Entry.Extended, &identities); err != nil { |
||||
|
return err |
||||
|
} |
||||
|
return nil |
||||
|
}); err != nil { |
||||
|
return err |
||||
|
} |
||||
|
return nil |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue