You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							193 lines
						
					
					
						
							5.1 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							193 lines
						
					
					
						
							5.1 KiB
						
					
					
				
								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.Fprint(writer, buf.String())
							 | 
						|
									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
							 | 
						|
								}
							 |