Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sdk): qos #124

Merged
merged 19 commits into from
Jan 21, 2025
132 changes: 132 additions & 0 deletions internal/sdk/cloudian/qos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package cloudian

import (
"context"
"encoding/json"
"fmt"
"strconv"
)

// QualityOfService configures data limits for a Group or User.
type QualityOfService struct {
// Soft is the soft (warning) limit.
Soft QualityOfServiceLimits
tenstad marked this conversation as resolved.
Show resolved Hide resolved
// Hard is the hard limit.
Hard QualityOfServiceLimits
}

// QualityOfService configures data limits.
type QualityOfServiceLimits struct {
// StorageQuotaKBytes is the limit for total stored data in KiB.
StorageQuotaKBytes *int64
// StorageQuotaCount is the limit for total number of objects.
StorageQuotaCount *int64
// RequestsPerMin is the limit for number of HTTP requests per minute.
RequestsPerMin *int64
// InboundKBytesPerMin is the limit for inbound data per minute in KiB.
InboundKBytesPerMin *int64
// OutboundKBytesPerMin is the limit for outbound data per minute in KiB.
OutboundKBytesPerMin *int64
}

// CreateQuota sets the QoS limits for a `User`. To change QoS limits, a delete and recreate is necessary.
func (client Client) CreateQuota(ctx context.Context, user User, qos QualityOfService) error {
rawParams := map[string]*int64{
"hlStorageQuotaKBytes": qos.Hard.StorageQuotaKBytes,
"wlStorageQuotaKBytes": qos.Soft.StorageQuotaKBytes,
"hlStorageQuotaCount": qos.Hard.StorageQuotaCount,
"wlStorageQuotaCount": qos.Soft.StorageQuotaCount,
"hlRequestRate": qos.Hard.RequestsPerMin,
"wlRequestRate": qos.Soft.RequestsPerMin,
"hlDataKBytesIn": qos.Hard.InboundKBytesPerMin,
"wlDataKBytesIn": qos.Soft.InboundKBytesPerMin,
"hlDataKBytesOut": qos.Hard.OutboundKBytesPerMin,
"wlDataKBytesOut": qos.Soft.OutboundKBytesPerMin,
}

params := make(map[string]string, len(rawParams))
for key, raw := range rawParams {
val := int64(-1)
if raw != nil {
val = *raw
}
if val < -1 {
val = -1
}
params[key] = strconv.FormatInt(val, 10)
tenstad marked this conversation as resolved.
Show resolved Hide resolved
}

resp, err := client.newRequest(ctx).
SetQueryParam("userId", user.UserID).
SetQueryParam("groupId", user.GroupID).
SetQueryParams(params).
Post("/qos/limits")
if err != nil {
return err
}

switch resp.StatusCode() {
case 200:
return nil
default:
return fmt.Errorf("SET quota unexpected status: %d", resp.StatusCode())
tenstad marked this conversation as resolved.
Show resolved Hide resolved
}
}

func (client Client) GetQuota(ctx context.Context, user User) (*QualityOfService, error) {

Check failure on line 76 in internal/sdk/cloudian/qos.go

View workflow job for this annotation

GitHub Actions / lint

cyclomatic complexity 16 of func `(Client).GetQuota` is high (> 10) (gocyclo)
resp, err := client.newRequest(ctx).
SetQueryParam("userId", user.UserID).
SetQueryParam("groupId", user.GroupID).
Get("/qos/limits")
if err != nil {
return nil, err
}

switch resp.StatusCode() {
case 200:
var data struct {
QOSLimitList []struct {
Type string
Value int64
} `json:"qosLimitList"`
}

if err := json.Unmarshal(resp.Body(), &data); err != nil {

Check failure on line 94 in internal/sdk/cloudian/qos.go

View workflow job for this annotation

GitHub Actions / lint

the given struct should be annotated with the `json` tag (musttag)
return nil, err
}

qos := QualityOfService{}
tenstad marked this conversation as resolved.
Show resolved Hide resolved
for _, item := range data.QOSLimitList {
if item.Value < 0 {
continue
}

v := &item.Value
switch item.Type {
case "STORAGE_QUOTA_KBYTES_LH":
qos.Hard.StorageQuotaKBytes = v
case "STORAGE_QUOTA_KBYTES_LW":
qos.Soft.StorageQuotaKBytes = v
case "STORAGE_QUOTA_COUNT_LH":
qos.Hard.StorageQuotaCount = v
case "STORAGE_QUOTA_COUNT_LW":
qos.Soft.StorageQuotaCount = v
case "REQUEST_RATE_LH":
qos.Hard.RequestsPerMin = v
case "REQUEST_RATE_LW":
qos.Soft.RequestsPerMin = v
case "DATAKBYTES_IN_LH":
qos.Hard.InboundKBytesPerMin = v
case "DATAKBYTES_IN_LW":
qos.Soft.InboundKBytesPerMin = v
case "DATAKBYTES_OUT_LH":
qos.Hard.OutboundKBytesPerMin = v
case "DATAKBYTES_OUT_LW":
qos.Soft.OutboundKBytesPerMin = v
}
}
return &qos, nil
default:
return nil, fmt.Errorf("SET quota unexpected status: %d", resp.StatusCode())
}
}
Loading