Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions restapi/admin_inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package restapi

import (
"context"
"encoding/binary"
"encoding/hex"
"fmt"
"hash/crc32"
"io"
"io/ioutil"
"net/http"

"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
"github.com/minio/madmin-go"
"github.com/secure-io/sio-go"
)

func registerInspectHandler(api *operations.ConsoleAPI) {
api.AdminAPIInspectHandler = admin_api.InspectHandlerFunc(func(params admin_api.InspectParams, principal *models.Principal) middleware.Responder {
k, r, err := getInspectResult(principal, &params)
isEncryptOn := params.Encrypt != nil && *params.Encrypt

if err != nil {
return admin_api.NewInspectDefault(int(err.Code)).WithPayload(err)
}

return middleware.ResponderFunc(processInspectResponse(isEncryptOn, k, r))
})
}

func getInspectResult(session *models.Principal, params *admin_api.InspectParams) (*[32]byte, io.ReadCloser, *models.Error) {
ctx := context.Background()
mAdmin, err := NewMinioAdminClient(session)
if err != nil {
return nil, nil, prepareError(err)
}

var cfg madmin.InspectOptions
cfg.File = params.File
cfg.Volume = params.Volume

// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := AdminClient{Client: mAdmin}

k, r, err := adminClient.inspect(ctx, cfg)

if err != nil {
return nil, nil, prepareError(err)
}
return &k, r, nil
}

//borrowed from mc cli
func decryptInspect(key [32]byte, r io.Reader) io.ReadCloser {
stream, err := sio.AES_256_GCM.Stream(key[:])
if err != nil {
return nil
}
nonce := make([]byte, stream.NonceSize())
return ioutil.NopCloser(stream.DecryptReader(r, nonce, nil))
}

func processInspectResponse(isEnc bool, k *[32]byte, r io.ReadCloser) func(w http.ResponseWriter, _ runtime.Producer) {
return func(w http.ResponseWriter, _ runtime.Producer) {
var id [4]byte
binary.LittleEndian.PutUint32(id[:], crc32.ChecksumIEEE(k[:]))
defer r.Close()

ext := "enc"
if !isEnc {
ext = "zip"
r = decryptInspect(*k, r)
}

fileName := fmt.Sprintf("inspect.%s.%s", hex.EncodeToString(id[:]), ext)

if isEnc {
// use cookie to transmit the Decryption Key.
hexKey := hex.EncodeToString(id[:]) + hex.EncodeToString(k[:])
cookie := http.Cookie{
Name: fileName,
Value: hexKey,
Path: "/",
MaxAge: 3000,
}
http.SetCookie(w, &cookie)
}

w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fileName))

_, err := io.Copy(w, r)

if err != nil {
LogError("Unable to write all the data: %v", err)
}
}
}
5 changes: 5 additions & 0 deletions restapi/client-admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,11 @@ func (ac AdminClient) addTier(ctx context.Context, cfg *madmin.TierConfig) error
return ac.Client.AddTier(ctx, cfg)
}

// implements madmin.Inspect()
func (ac AdminClient) inspect(ctx context.Context, insOpts madmin.InspectOptions) ([32]byte, io.ReadCloser, error) {
return ac.Client.Inspect(ctx, insOpts)
}

// implements madmin.EditTier()
func (ac AdminClient) editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error {
return ac.Client.EditTier(ctx, tierName, creds)
Expand Down
2 changes: 2 additions & 0 deletions restapi/configure_console.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
registerSubnetHandlers(api)
// Register Account handlers
registerAdminTiersHandlers(api)
//Register Inspect Handler
registerInspectHandler(api)

// Operator Console

Expand Down
90 changes: 90 additions & 0 deletions restapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 88 additions & 0 deletions restapi/operations/admin_api/inspect.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading