oss/lib/stat.go (252 lines of code) (raw):

package lib import ( "fmt" "net/http" "sort" "strings" "time" oss "github.com/aliyun/aliyun-oss-go-sdk/oss" ) var specChineseStat = SpecText{ synopsisText: "显示bucket或者object的描述信息", paramText: "cloud_url [options]", syntaxText: ` ossutil stat oss://bucket[/object] [--encoding-type url] [--version-id versionId] [--payer requester] [-c file] `, detailHelpText: ` 该命令获取指定bucket或者object的描述信息。通过set-meta命令设置的object元信息,可以通过 该命令查看。 用法: 该命令有两种用法: 1) ossutil stat oss://bucket [--encoding-type url] ossutil显示指定bucket的信息,包括创建时间,location,访问的外网域名,内网域名,拥 有者,acl信息。 2) ossutil stat oss://bucket/object [--encoding-type url] [--version-id versionId] ossutil显示指定object的元信息,包括文件大小,最新更新时间,etag,文件类型,acl,文 件的自定义meta等信息。 `, sampleText: ` ossutil stat oss://bucket1 ossutil stat oss://bucket1/object ossutil stat oss://bucket1/object --version-id versionId ossutil stat oss://bucket1/%e4%b8%ad%e6%96%87 --encoding-type url ossutil stat oss://bucket1/object --payer requester `, } var specEnglishStat = SpecText{ synopsisText: "Display meta information of bucket or objects", paramText: "cloud_url [options]", syntaxText: ` ossutil stat oss://bucket[/object] [--encoding-type url] [--version-id versionId] [--payer requester] [-c file] `, detailHelpText: ` The command display the meta information of bucket or objects. The object meta information setted through set-meta command, can be check by the command. Usage: There are three usages: 1) ossutil stat oss://bucket [--encoding-type url] ossutil display bucket meta info, include creation date, location, extranet endpoint, intranet endpoint, Owner and acl info. 2) ossutil stat oss://bucket/object [--encoding-type url] [--version-id versionId] ossutil display object meta info, include file size, last modify time, etag, content-type, user meta etc. `, sampleText: ` ossutil stat oss://bucket1 ossutil stat oss://bucket1/object ossutil stat oss://bucket1/object --version-id versionId ossutil stat oss://bucket1/%e4%b8%ad%e6%96%87 --encoding-type url ossutil stat oss://bucket1/object --payer requester `, } // StatCommand is the command get bucket's or objects' meta information type StatCommand struct { command Command versionId string commonOptions []oss.Option } var statCommand = StatCommand{ command: Command{ name: "stat", nameAlias: []string{"meta", "info"}, minArgc: 1, maxArgc: 1, specChinese: specChineseStat, specEnglish: specEnglishStat, group: GroupTypeNormalCommand, validOptionNames: []string{ OptionEncodingType, OptionConfigFile, OptionEndpoint, OptionAccessKeyID, OptionAccessKeySecret, OptionSTSToken, OptionProxyHost, OptionProxyUser, OptionProxyPwd, OptionRetryTimes, OptionLogLevel, OptionVersionId, OptionRequestPayer, OptionPassword, OptionMode, OptionECSRoleName, OptionTokenTimeout, OptionRamRoleArn, OptionRoleSessionName, OptionExternalId, OptionReadTimeout, OptionConnectTimeout, OptionSTSRegion, OptionSkipVerifyCert, OptionUserAgent, OptionSignVersion, OptionRegion, OptionCloudBoxID, OptionForcePathStyle, }, }, } // function for FormatHelper interface func (sc *StatCommand) formatHelpForWhole() string { return sc.command.formatHelpForWhole() } func (sc *StatCommand) formatIndependHelp() string { return sc.command.formatIndependHelp() } // Init simulate inheritance, and polymorphism func (sc *StatCommand) Init(args []string, options OptionMapType) error { return sc.command.Init(args, options, sc) } // RunCommand simulate inheritance, and polymorphism func (sc *StatCommand) RunCommand() error { sc.versionId, _ = GetString(OptionVersionId, sc.command.options) encodingType, _ := GetString(OptionEncodingType, sc.command.options) cloudURL, err := CloudURLFromString(sc.command.args[0], encodingType) if err != nil { return err } if cloudURL.bucket == "" { return fmt.Errorf("invalid cloud url: %s, miss bucket", sc.command.args[0]) } payer, _ := GetString(OptionRequestPayer, sc.command.options) if payer != "" { if payer != strings.ToLower(string(oss.Requester)) { return fmt.Errorf("invalid request payer: %s, please check", payer) } sc.commonOptions = append(sc.commonOptions, oss.RequestPayer(oss.PayerType(payer))) } bucket, err := sc.command.ossBucket(cloudURL.bucket) if err != nil { return err } if cloudURL.object == "" { return sc.bucketStat(bucket, cloudURL) } return sc.objectStat(bucket, cloudURL) } func (sc *StatCommand) bucketStat(bucket *oss.Bucket, cloudURL CloudURL) error { // TODO: go sdk should implement GetBucketInfo gbar, err := sc.ossGetBucketStatRetry(bucket) if err != nil { return err } fmt.Printf("%-22s: %s\n", StatName, gbar.BucketInfo.Name) fmt.Printf("%-22s: %s\n", StatLocation, gbar.BucketInfo.Location) fmt.Printf("%-22s: %s\n", StatCreationDate, utcToLocalTime(gbar.BucketInfo.CreationDate)) fmt.Printf("%-22s: %s\n", StatExtranetEndpoint, gbar.BucketInfo.ExtranetEndpoint) fmt.Printf("%-22s: %s\n", StatIntranetEndpoint, gbar.BucketInfo.IntranetEndpoint) fmt.Printf("%-22s: %s\n", StatACL, gbar.BucketInfo.ACL) fmt.Printf("%-22s: %s\n", StatOwner, gbar.BucketInfo.Owner.ID) fmt.Printf("%-22s: %s\n", StatStorageClass, gbar.BucketInfo.StorageClass) if len(gbar.BucketInfo.RedundancyType) > 0 { fmt.Printf("%-22s: %s\n", StatRedundancyType, gbar.BucketInfo.RedundancyType) } if len(gbar.BucketInfo.SseRule.SSEAlgorithm) > 0 { fmt.Printf("%-22s: %s\n", StatSSEAlgorithm, gbar.BucketInfo.SseRule.SSEAlgorithm) } if len(gbar.BucketInfo.SseRule.KMSMasterKeyID) > 0 { fmt.Printf("%-22s: %s\n", StatKMSMasterKeyID, gbar.BucketInfo.SseRule.KMSMasterKeyID) } if len(gbar.BucketInfo.SseRule.KMSDataEncryption) > 0 { fmt.Printf("%-22s: %s\n", StatKMSDataEncryption, gbar.BucketInfo.SseRule.KMSDataEncryption) } fmt.Printf("%-22s: %s\n", StatTransferAcceleration, gbar.BucketInfo.TransferAcceleration) fmt.Printf("%-22s: %s\n", StatCrossRegionReplication, gbar.BucketInfo.CrossRegionReplication) if len(gbar.BucketInfo.AccessMonitor) > 0 { fmt.Printf("%-22s: %s\n", StatAccessMonitor, gbar.BucketInfo.AccessMonitor) } return nil } func (sc *StatCommand) ossGetBucketStatRetry(bucket *oss.Bucket) (oss.GetBucketInfoResult, error) { retryTimes, _ := GetInt(OptionRetryTimes, sc.command.options) for i := 1; ; i++ { gbar, err := bucket.Client.GetBucketInfo(bucket.BucketName, sc.commonOptions...) if err == nil { return gbar, err } if int64(i) >= retryTimes { return gbar, BucketError{err, bucket.BucketName} } } } func (sc *StatCommand) objectStat(bucket *oss.Bucket, cloudURL CloudURL) error { // acl info goar, err := sc.ossGetObjectACLRetry(bucket, cloudURL.object) if err != nil { return err } // normal info statOptions := []oss.Option{} if len(sc.versionId) > 0 { statOptions = append(statOptions, oss.VersionId(sc.versionId)) } statOptions = append(statOptions, sc.commonOptions...) props, err := sc.command.ossGetObjectStatRetry(bucket, cloudURL.object, statOptions...) if err != nil { return err } sortNames := []string{} attrMap := map[string]string{} maxNameLen := 0 for name := range props { if len(name) > maxNameLen { maxNameLen = len(name) } ln := strings.ToLower(name) if ln != strings.ToLower(oss.HTTPHeaderDate) && ln != strings.ToLower(oss.HTTPHeaderOssRequestID) && ln != strings.ToLower(oss.HTTPHeaderServer) && ln != "x-oss-server-time" && ln != "connection" { sortNames = append(sortNames, name) attrMap[name] = props.Get(name) } } sortNames = append(sortNames, "Owner") sortNames = append(sortNames, "ACL") attrMap[StatOwner] = goar.Owner.ID attrMap[StatACL] = goar.ACL if lm, err := time.Parse(http.TimeFormat, attrMap[StatLastModified]); err == nil { attrMap[StatLastModified] = fmt.Sprintf("%s", utcToLocalTime(lm.UTC())) } sort.Strings(sortNames) for _, name := range sortNames { if strings.ToLower(name) != "etag" { fmt.Printf("%-[1]*s: %s\n", maxNameLen+2, name, attrMap[name]) } else { fmt.Printf("%-[1]*s: %s\n", maxNameLen+2, name, strings.Trim(attrMap[name], "\"")) } } return nil } func (sc *StatCommand) ossGetObjectACLRetry(bucket *oss.Bucket, object string) (oss.GetObjectACLResult, error) { retryTimes, _ := GetInt(OptionRetryTimes, sc.command.options) aclOptions := []oss.Option{} if len(sc.versionId) > 0 { aclOptions = append(aclOptions, oss.VersionId(sc.versionId)) } aclOptions = append(aclOptions, sc.commonOptions...) for i := 1; ; i++ { goar, err := bucket.GetObjectACL(object, aclOptions...) if err == nil { return goar, err } if int64(i) >= retryTimes { return goar, ObjectError{err, bucket.BucketName, object} } } }