123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- package shell
- import (
- "bytes"
- "flag"
- "fmt"
- "io"
- "sort"
- "strings"
- "github.com/seaweedfs/seaweedfs/weed/filer"
- "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
- "github.com/seaweedfs/seaweedfs/weed/pb/iam_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) HasTag(CommandTag) bool {
- return false
- }
- func (c *commandS3Configure) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
- s3ConfigureCommand := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
- actions := s3ConfigureCommand.String("actions", "", "comma separated actions names: Read,Write,List,Tagging,Admin")
- 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 buf bytes.Buffer
- if err = commandEnv.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
- return filer.ReadEntry(commandEnv.MasterClient, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf)
- }); err != nil && err != filer_pb.ErrNotFound {
- return err
- }
- s3cfg := &iam_pb.S3ApiConfiguration{}
- if buf.Len() > 0 {
- if err = filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg); err != nil {
- return err
- }
- }
- idx := 0
- changed := false
- if *user != "" {
- for i, identity := range s3cfg.Identities {
- if *user == identity.Name {
- idx = i
- changed = true
- break
- }
- }
- }
- var cmdActions []string
- for _, action := range strings.Split(*actions, ",") {
- if *buckets == "" {
- cmdActions = append(cmdActions, action)
- } else {
- for _, bucket := range strings.Split(*buckets, ",") {
- cmdActions = append(cmdActions, fmt.Sprintf("%s:%s", action, bucket))
- }
- }
- }
- if changed {
- infoAboutSimulationMode(writer, *apply, "-apply")
- if *isDelete {
- var exists []int
- for _, cmdAction := range cmdActions {
- for i, currentAction := range s3cfg.Identities[idx].Actions {
- if cmdAction == currentAction {
- exists = append(exists, i)
- }
- }
- }
- sort.Sort(sort.Reverse(sort.IntSlice(exists)))
- for _, i := range exists {
- s3cfg.Identities[idx].Actions = append(
- s3cfg.Identities[idx].Actions[:i],
- s3cfg.Identities[idx].Actions[i+1:]...,
- )
- }
- if *accessKey != "" {
- exists = []int{}
- for i, credential := range s3cfg.Identities[idx].Credentials {
- if credential.AccessKey == *accessKey {
- exists = append(exists, i)
- }
- }
- sort.Sort(sort.Reverse(sort.IntSlice(exists)))
- for _, i := range exists {
- s3cfg.Identities[idx].Credentials = append(
- s3cfg.Identities[idx].Credentials[:i],
- s3cfg.Identities[idx].Credentials[i+1:]...,
- )
- }
- }
- if *actions == "" && *accessKey == "" && *buckets == "" {
- s3cfg.Identities = append(s3cfg.Identities[:idx], s3cfg.Identities[idx+1:]...)
- }
- } else {
- if *actions != "" {
- for _, cmdAction := range cmdActions {
- found := false
- for _, action := range s3cfg.Identities[idx].Actions {
- if cmdAction == action {
- found = true
- break
- }
- }
- if !found {
- s3cfg.Identities[idx].Actions = append(s3cfg.Identities[idx].Actions, cmdAction)
- }
- }
- }
- if *accessKey != "" && *user != "anonymous" {
- found := false
- for _, credential := range s3cfg.Identities[idx].Credentials {
- if credential.AccessKey == *accessKey {
- found = true
- credential.SecretKey = *secretKey
- break
- }
- }
- if !found {
- s3cfg.Identities[idx].Credentials = append(s3cfg.Identities[idx].Credentials, &iam_pb.Credential{
- AccessKey: *accessKey,
- SecretKey: *secretKey,
- })
- }
- }
- }
- } else if *user != "" && *actions != "" {
- infoAboutSimulationMode(writer, *apply, "-apply")
- identity := iam_pb.Identity{
- Name: *user,
- Actions: cmdActions,
- Credentials: []*iam_pb.Credential{},
- }
- if *user != "anonymous" {
- identity.Credentials = append(identity.Credentials,
- &iam_pb.Credential{AccessKey: *accessKey, SecretKey: *secretKey})
- }
- s3cfg.Identities = append(s3cfg.Identities, &identity)
- }
- if err = filer.CheckDuplicateAccessKey(s3cfg); err != nil {
- return err
- }
- buf.Reset()
- filer.ProtoToText(&buf, s3cfg)
- fmt.Fprintf(writer, string(buf.Bytes()))
- fmt.Fprintln(writer)
- if *apply {
- if err := commandEnv.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
- return filer.SaveInsideFiler(client, filer.IamConfigDirectory, filer.IamIdentityFile, buf.Bytes())
- }); err != nil {
- return err
- }
- }
- return nil
- }
|