Skip to content

Commit 93e1168

Browse files
authored
Add fields to tenant's info api (#192)
The response includes Image, TotalSize which is the available size and UsedSize which is the real Disk Space
1 parent 328133d commit 93e1168

File tree

11 files changed

+383
-212
lines changed

11 files changed

+383
-212
lines changed

go.sum

Lines changed: 1 addition & 161 deletions
Large diffs are not rendered by default.

models/tenant.go

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/auth/jwt.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ import (
2828
"log"
2929
"net/http"
3030
"strings"
31+
"time"
3132

3233
jwtgo "github.com/dgrijalva/jwt-go"
3334
"github.com/go-openapi/swag"
3435
xjwt "github.com/minio/mcs/pkg/auth/jwt"
3536
"github.com/minio/minio-go/v6/pkg/credentials"
36-
"github.com/minio/minio/cmd"
3737
uuid "github.com/satori/go.uuid"
3838
"golang.org/x/crypto/pbkdf2"
3939
)
@@ -103,7 +103,7 @@ func NewJWTWithClaimsForClient(credentials *credentials.Value, actions []string,
103103
return "", err
104104
}
105105
claims := xjwt.NewStandardClaims()
106-
claims.SetExpiry(cmd.UTCNow().Add(xjwt.GetMcsSTSAndJWTDurationTime()))
106+
claims.SetExpiry(time.Now().UTC().Add(xjwt.GetMcsSTSAndJWTDurationTime()))
107107
claims.SetSubject(uuid.NewV4().String())
108108
claims.SetData(encryptedClaims)
109109
claims.SetAudience(audience)

restapi/admin_info.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ func registerAdminInfoHandlers(api *operations.McsAPI) {
4242
}
4343

4444
type usageInfo struct {
45-
Buckets int64
46-
Objects int64
47-
Usage int64
45+
Buckets int64
46+
Objects int64
47+
Usage int64
48+
DisksUsage int64
4849
}
4950

5051
// getAdminInfo invokes admin info and returns a parsed `usageInfo` structure
@@ -55,10 +56,19 @@ func getAdminInfo(ctx context.Context, client MinioAdmin) (*usageInfo, error) {
5556
}
5657
// we are trimming uint64 to int64 this will report an incorrect measurement for numbers greater than
5758
// 9,223,372,036,854,775,807
59+
60+
var usedSpace int64
61+
for _, serv := range serverInfo.Servers {
62+
for _, disk := range serv.Disks {
63+
usedSpace += int64(disk.UsedSpace)
64+
}
65+
}
66+
5867
return &usageInfo{
59-
Buckets: int64(serverInfo.Buckets.Count),
60-
Objects: int64(serverInfo.Objects.Count),
61-
Usage: int64(serverInfo.Usage.Size),
68+
Buckets: int64(serverInfo.Buckets.Count),
69+
Objects: int64(serverInfo.Objects.Count),
70+
Usage: int64(serverInfo.Usage.Size),
71+
DisksUsage: usedSpace,
6272
}, nil
6373
}
6474

restapi/tenants.go renamed to restapi/admin_tenants.go

Lines changed: 99 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import (
2121
"encoding/json"
2222
"fmt"
2323
"log"
24+
"net"
2425
"net/http"
2526
"os"
27+
"strconv"
2628
"strings"
2729
"time"
2830

@@ -32,6 +34,7 @@ import (
3234
corev1 "k8s.io/api/core/v1"
3335

3436
"github.com/minio/mcs/cluster"
37+
madmin "github.com/minio/minio/pkg/madmin"
3538

3639
"github.com/go-openapi/runtime/middleware"
3740
"github.com/go-openapi/swag"
@@ -128,45 +131,127 @@ func getDeleteTenantResponse(token string, params admin_api.DeleteTenantParams)
128131
return deleteTenantAction(context.Background(), opClient, params.Namespace, params.Tenant)
129132
}
130133

131-
func getTenantInfoResponse(token string, params admin_api.TenantInfoParams) (*models.Tenant, error) {
132-
opClient, err := cluster.OperatorClient(token)
134+
func identifyMinioInstanceScheme(mi *operator.MinIOInstance) string {
135+
scheme := "http"
136+
if mi.RequiresAutoCertSetup() || mi.RequiresExternalCertSetup() {
137+
scheme = "https"
138+
}
139+
return scheme
140+
}
141+
142+
func getTenantAdminClient(ctx context.Context, client K8sClient, namespace, tenantName, serviceName, scheme string) (*madmin.AdminClient, error) {
143+
// get admin credentials from secret
144+
creds, err := client.getSecret(ctx, namespace, fmt.Sprintf("%s-secret", tenantName), metav1.GetOptions{})
133145
if err != nil {
134146
return nil, err
135147
}
148+
accessKey, ok := creds.Data["accesskey"]
149+
if !ok {
150+
log.Println("tenant's secret doesn't contain accesskey")
151+
return nil, errorGeneric
152+
}
153+
secretkey, ok := creds.Data["secretkey"]
154+
if !ok {
155+
log.Println("tenant's secret doesn't contain secretkey")
156+
return nil, errorGeneric
157+
}
158+
service, err := client.getService(ctx, namespace, serviceName, metav1.GetOptions{})
159+
if err != nil {
160+
return nil, err
161+
}
162+
mAdmin, pErr := NewAdminClient(scheme+"://"+net.JoinHostPort(service.Spec.ClusterIP, strconv.Itoa(operator.MinIOPort)), string(accessKey), string(secretkey))
163+
if pErr != nil {
164+
return nil, pErr.Cause
165+
}
166+
return mAdmin, nil
167+
}
136168

137-
minInst, err := opClient.OperatorV1().MinIOInstances(params.Namespace).Get(context.Background(), params.Tenant, metav1.GetOptions{})
169+
func getMinioInstance(ctx context.Context, operatorClient OperatorClient, namespace, tenantName string) (*operator.MinIOInstance, error) {
170+
minInst, err := operatorClient.MinIOInstanceGet(ctx, namespace, tenantName, metav1.GetOptions{})
138171
if err != nil {
139172
return nil, err
140173
}
174+
return minInst, nil
175+
}
141176

177+
func getTenantInfo(minioInstance *operator.MinIOInstance, tenantInfo *usageInfo) *models.Tenant {
142178
var instanceCount int64
143179
var volumeCount int64
144-
for _, zone := range minInst.Spec.Zones {
180+
for _, zone := range minioInstance.Spec.Zones {
145181
instanceCount = instanceCount + int64(zone.Servers)
146-
volumeCount = volumeCount + int64(zone.Servers*int32(minInst.Spec.VolumesPerServer))
182+
volumeCount = volumeCount + int64(zone.Servers*int32(minioInstance.Spec.VolumesPerServer))
147183
}
148184

149185
var zones []*models.Zone
150186

151-
for _, z := range minInst.Spec.Zones {
187+
for _, z := range minioInstance.Spec.Zones {
152188
zones = append(zones, &models.Zone{
153189
Name: z.Name,
154190
Servers: int64(z.Servers),
155191
})
156192
}
157193

158194
return &models.Tenant{
159-
CreationDate: minInst.ObjectMeta.CreationTimestamp.String(),
195+
CreationDate: minioInstance.ObjectMeta.CreationTimestamp.String(),
160196
InstanceCount: instanceCount,
161-
Name: params.Tenant,
162-
VolumesPerServer: int64(minInst.Spec.VolumesPerServer),
197+
Name: minioInstance.Name,
198+
VolumesPerServer: int64(minioInstance.Spec.VolumesPerServer),
163199
VolumeCount: volumeCount,
164-
VolumeSize: minInst.Spec.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value(),
165-
ZoneCount: int64(len(minInst.Spec.Zones)),
166-
CurrentState: minInst.Status.CurrentState,
200+
VolumeSize: minioInstance.Spec.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value(),
201+
TotalSize: int64(minioInstance.Spec.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value() * volumeCount),
202+
ZoneCount: int64(len(minioInstance.Spec.Zones)),
203+
CurrentState: minioInstance.Status.CurrentState,
167204
Zones: zones,
168-
Namespace: minInst.ObjectMeta.Namespace,
169-
}, nil
205+
Namespace: minioInstance.ObjectMeta.Namespace,
206+
Image: minioInstance.Spec.Image,
207+
UsedSize: tenantInfo.DisksUsage,
208+
}
209+
}
210+
211+
func getTenantInfoResponse(token string, params admin_api.TenantInfoParams) (*models.Tenant, error) {
212+
// 20 seconds timeout
213+
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
214+
defer cancel()
215+
216+
opClientClientSet, err := cluster.OperatorClient(token)
217+
if err != nil {
218+
return nil, err
219+
}
220+
clientset, err := cluster.K8sClient(token)
221+
if err != nil {
222+
log.Println("error getting k8sClient:", err)
223+
return nil, err
224+
}
225+
226+
opClient := &operatorClient{
227+
client: opClientClientSet,
228+
}
229+
k8sClient := &k8sClient{
230+
client: clientset,
231+
}
232+
233+
minInst, err := getMinioInstance(ctx, opClient, params.Namespace, params.Tenant)
234+
if err != nil {
235+
log.Println("error getting minioInstance:", err)
236+
return nil, err
237+
}
238+
minioInstanceScheme := identifyMinioInstanceScheme(minInst)
239+
mAdmin, err := getTenantAdminClient(ctx, k8sClient, params.Namespace, params.Tenant, minInst.Spec.ServiceName, minioInstanceScheme)
240+
if err != nil {
241+
log.Println("error getting tenant's admin client:", err)
242+
return nil, err
243+
}
244+
// create a minioClient interface implementation
245+
// defining the client to be used
246+
adminClient := adminClient{client: mAdmin}
247+
// serialize output
248+
adminInfo, err := getAdminInfo(ctx, adminClient)
249+
if err != nil {
250+
log.Println("error getting admin info:", err)
251+
return nil, err
252+
}
253+
info := getTenantInfo(minInst, adminInfo)
254+
return info, nil
170255
}
171256

172257
func listTenants(ctx context.Context, operatorClient OperatorClient, namespace string, limit *int32) (*models.ListTenantsResponse, error) {

0 commit comments

Comments
 (0)