This repository has been archived by the owner on Mar 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Labels are used to tag different object, and perform collective operation based on label configuration values More information on #issue:1094 Signed-off-by: Mohammed Rafi KC <[email protected]>
- Loading branch information
Showing
16 changed files
with
885 additions
and
46 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package labelcommands | ||
|
||
import ( | ||
"github.com/gluster/glusterd2/glusterd2/servers/rest/route" | ||
"github.com/gluster/glusterd2/pkg/api" | ||
"github.com/gluster/glusterd2/pkg/utils" | ||
) | ||
|
||
// Command is a structure which implements GlusterD Command interface | ||
type Command struct { | ||
} | ||
|
||
// Routes returns list of REST API routes to register with Glusterd | ||
func (c *Command) Routes() route.Routes { | ||
return route.Routes{ | ||
route.Route{ | ||
Name: "LabelCreate", | ||
Method: "POST", | ||
Pattern: "/labels", | ||
Version: 1, | ||
RequestType: utils.GetTypeString((*api.LabelCreateReq)(nil)), | ||
ResponseType: utils.GetTypeString((*api.LabelCreateResp)(nil)), | ||
HandlerFunc: labelCreateHandler}, | ||
route.Route{ | ||
Name: "LabelInfo", | ||
Method: "GET", | ||
Pattern: "/labels/{labelname}", | ||
Version: 1, | ||
ResponseType: utils.GetTypeString((*api.LabelGetResp)(nil)), | ||
HandlerFunc: labelInfoHandler}, | ||
route.Route{ | ||
Name: "LabelListAll", | ||
Method: "GET", | ||
Pattern: "/labels", | ||
Version: 1, | ||
ResponseType: utils.GetTypeString((*api.LabelListResp)(nil)), | ||
HandlerFunc: labelListHandler}, | ||
route.Route{ | ||
Name: "LabelDelete", | ||
Method: "DELETE", | ||
Pattern: "/labels/{labelname}", | ||
Version: 1, | ||
HandlerFunc: labelDeleteHandler}, | ||
route.Route{ | ||
Name: "LabelConfigSet", | ||
Method: "POST", | ||
Pattern: "/labels/{labelname}/config", | ||
Version: 1, | ||
RequestType: utils.GetTypeString((*api.LabelSetReq)(nil)), | ||
ResponseType: utils.GetTypeString((*api.LabelConfigResp)(nil)), | ||
HandlerFunc: labelConfigSetHandler}, | ||
route.Route{ | ||
Name: "LabelConfigReset", | ||
Method: "DELETE", | ||
Pattern: "/labels/{labelname}/config", | ||
Version: 1, | ||
RequestType: utils.GetTypeString((*api.LabelResetReq)(nil)), | ||
ResponseType: utils.GetTypeString((*api.LabelConfigResp)(nil)), | ||
HandlerFunc: labelConfigResetHandler}, | ||
} | ||
} | ||
|
||
// RegisterStepFuncs registers transaction step functions with | ||
// Glusterd Transaction framework | ||
func (c *Command) RegisterStepFuncs() { | ||
registerLabelCreateStepFuncs() | ||
registerLabelDeleteStepFuncs() | ||
registerLabelConfigSetStepFuncs() | ||
registerLabelConfigResetStepFuncs() | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package labelcommands | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/gluster/glusterd2/glusterd2/gdctx" | ||
"github.com/gluster/glusterd2/glusterd2/label" | ||
restutils "github.com/gluster/glusterd2/glusterd2/servers/rest/utils" | ||
"github.com/gluster/glusterd2/glusterd2/transaction" | ||
"github.com/gluster/glusterd2/pkg/api" | ||
gderrors "github.com/gluster/glusterd2/pkg/errors" | ||
|
||
"github.com/pborman/uuid" | ||
) | ||
|
||
const maxSnapCount = 256 | ||
|
||
func validateLabel(info *label.Info) error { | ||
|
||
if info.SnapMaxHardLimit > maxSnapCount { | ||
return fmt.Errorf("Snap-max-hard-limit count cannot exceed more than %d", maxSnapCount) | ||
} | ||
if info.SnapMaxSoftLimit > info.SnapMaxHardLimit { | ||
return errors.New("snap-soft-limit cannot exceed more than snap-max-hard-limit") | ||
} | ||
return nil | ||
} | ||
|
||
func newLabelInfo(req *api.LabelCreateReq) *label.Info { | ||
var labelInfo label.Info | ||
|
||
labelInfo.Name = req.Name | ||
labelInfo.SnapMaxHardLimit = req.SnapMaxHardLimit | ||
labelInfo.SnapMaxSoftLimit = req.SnapMaxSoftLimit | ||
labelInfo.ActivateOnCreate = req.ActivateOnCreate | ||
labelInfo.AutoDelete = req.AutoDelete | ||
labelInfo.Description = req.Description | ||
|
||
return &labelInfo | ||
} | ||
|
||
func storeLabel(c transaction.TxnCtx) error { | ||
|
||
var labelInfo label.Info | ||
|
||
if err := c.Get("label", &labelInfo); err != nil { | ||
return err | ||
} | ||
if err := label.AddOrUpdateLabelFunc(&labelInfo); err != nil { | ||
c.Logger().WithError(err).WithField( | ||
"label", labelInfo.Name).Debug("storeLabel: failed to store label info") | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func registerLabelCreateStepFuncs() { | ||
transaction.RegisterStepFunc(storeLabel, "label-create.Store") | ||
} | ||
|
||
func labelCreateHandler(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
logger := gdctx.GetReqLogger(ctx) | ||
var req api.LabelCreateReq | ||
|
||
if err := restutils.UnmarshalRequest(r, &req); err != nil { | ||
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, gderrors.ErrJSONParsingFailed) | ||
return | ||
} | ||
if label.ExistsFunc(req.Name) { | ||
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, gderrors.ErrLabelExists) | ||
return | ||
} | ||
|
||
/* | ||
TODO : label name validation | ||
*/ | ||
|
||
labelInfo := newLabelInfo(&req) | ||
if err := validateLabel(labelInfo); err != nil { | ||
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, err) | ||
return | ||
} | ||
|
||
txn, err := transaction.NewTxnWithLocks(ctx, req.Name) | ||
if err != nil { | ||
status, err := restutils.ErrToStatusCode(err) | ||
restutils.SendHTTPError(ctx, w, status, err) | ||
return | ||
} | ||
defer txn.Done() | ||
|
||
txn.Steps = []*transaction.Step{ | ||
{ | ||
DoFunc: "label-create.Store", | ||
Nodes: []uuid.UUID{gdctx.MyUUID}, | ||
}, | ||
} | ||
|
||
if err = txn.Ctx.Set("label", &labelInfo); err != nil { | ||
logger.WithError(err).Error("failed to set request in transaction context") | ||
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
return | ||
} | ||
|
||
if err = txn.Do(); err != nil { | ||
logger.WithError(err).Error("label create transaction failed") | ||
status, err := restutils.ErrToStatusCode(err) | ||
restutils.SendHTTPError(ctx, w, status, err) | ||
return | ||
} | ||
|
||
labelInfo, err = label.GetLabel(req.Name) | ||
if err != nil { | ||
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
return | ||
} | ||
|
||
txn.Ctx.Logger().WithField("LabelName", req.Name).Info("new label created") | ||
|
||
resp := createLabelCreateResp(labelInfo) | ||
restutils.SetLocationHeader(r, w, labelInfo.Name) | ||
restutils.SendHTTPResponse(ctx, w, http.StatusCreated, resp) | ||
} | ||
|
||
func createLabelCreateResp(info *label.Info) *api.LabelCreateResp { | ||
return (*api.LabelCreateResp)(label.CreateLabelInfoResp(info)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package labelcommands | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/gluster/glusterd2/glusterd2/gdctx" | ||
"github.com/gluster/glusterd2/glusterd2/label" | ||
restutils "github.com/gluster/glusterd2/glusterd2/servers/rest/utils" | ||
"github.com/gluster/glusterd2/glusterd2/transaction" | ||
"github.com/gorilla/mux" | ||
"github.com/pborman/uuid" | ||
) | ||
|
||
func registerLabelDeleteStepFuncs() { | ||
transaction.RegisterStepFunc(deleteLabel, "label-delete.Store") | ||
} | ||
|
||
func deleteLabel(c transaction.TxnCtx) error { | ||
|
||
var labelInfo label.Info | ||
if err := c.Get("labelinfo", &labelInfo); err != nil { | ||
return err | ||
} | ||
|
||
err := label.DeleteLabel(&labelInfo) | ||
return err | ||
} | ||
|
||
func labelDeleteHandler(w http.ResponseWriter, r *http.Request) { | ||
|
||
ctx := r.Context() | ||
logger := gdctx.GetReqLogger(ctx) | ||
|
||
labelname := mux.Vars(r)["labelname"] | ||
labelInfo, err := label.GetLabel(labelname) | ||
if err != nil { | ||
status, err := restutils.ErrToStatusCode(err) | ||
restutils.SendHTTPError(ctx, w, status, err) | ||
return | ||
} | ||
|
||
txn, err := transaction.NewTxnWithLocks(ctx, labelname) | ||
if err != nil { | ||
status, err := restutils.ErrToStatusCode(err) | ||
restutils.SendHTTPError(ctx, w, status, err) | ||
return | ||
} | ||
defer txn.Done() | ||
|
||
if labelname == (label.DefaultLabel).Name { | ||
errMsg := "Default label cannot be deleted." | ||
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, errMsg) | ||
return | ||
} | ||
|
||
if len(labelInfo.SnapList) > 0 { | ||
errMsg := fmt.Sprintf("Cannot delete Label %s ,as it has %d snapshots tagged.", labelname, len(labelInfo.SnapList)) | ||
restutils.SendHTTPError(ctx, w, http.StatusFailedDependency, errMsg) | ||
return | ||
} | ||
txn.Steps = []*transaction.Step{ | ||
{ | ||
DoFunc: "label-delete.Store", | ||
Nodes: []uuid.UUID{gdctx.MyUUID}, | ||
}, | ||
} | ||
|
||
if err := txn.Ctx.Set("labelinfo", labelInfo); err != nil { | ||
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
return | ||
} | ||
|
||
if err := txn.Do(); err != nil { | ||
logger.WithError(err).WithField( | ||
"label", labelname).Error("transaction to delete label failed") | ||
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err) | ||
return | ||
} | ||
|
||
logger.WithField("label-name", labelname).Info("label deleted") | ||
restutils.SendHTTPResponse(ctx, w, http.StatusNoContent, nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package labelcommands | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/gluster/glusterd2/glusterd2/label" | ||
restutils "github.com/gluster/glusterd2/glusterd2/servers/rest/utils" | ||
"github.com/gluster/glusterd2/pkg/api" | ||
"github.com/gorilla/mux" | ||
) | ||
|
||
func labelInfoHandler(w http.ResponseWriter, r *http.Request) { | ||
|
||
ctx := r.Context() | ||
|
||
labelname := mux.Vars(r)["labelname"] | ||
labelInfo, err := label.GetLabel(labelname) | ||
if err != nil { | ||
status, err := restutils.ErrToStatusCode(err) | ||
restutils.SendHTTPError(ctx, w, status, err) | ||
return | ||
} | ||
|
||
resp := createLabelGetResp(labelInfo) | ||
restutils.SendHTTPResponse(ctx, w, http.StatusOK, resp) | ||
} | ||
|
||
func createLabelGetResp(info *label.Info) *api.LabelGetResp { | ||
return (*api.LabelGetResp)(label.CreateLabelInfoResp(info)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package labelcommands | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/gluster/glusterd2/glusterd2/label" | ||
restutils "github.com/gluster/glusterd2/glusterd2/servers/rest/utils" | ||
"github.com/gluster/glusterd2/pkg/api" | ||
) | ||
|
||
func labelListHandler(w http.ResponseWriter, r *http.Request) { | ||
|
||
ctx := r.Context() | ||
|
||
labelInfos, err := label.GetLabels() | ||
if err != nil { | ||
status, err := restutils.ErrToStatusCode(err) | ||
restutils.SendHTTPError(ctx, w, status, err) | ||
return | ||
} | ||
|
||
resp := createLabelListResp(labelInfos) | ||
restutils.SendHTTPResponse(ctx, w, http.StatusOK, resp) | ||
} | ||
|
||
func createLabelListResp(infos []*label.Info) *api.LabelListResp { | ||
var resp = make(api.LabelListResp, len(infos)) | ||
|
||
for index, v := range infos { | ||
resp[index] = *(createLabelGetResp(v)) | ||
} | ||
|
||
return &resp | ||
} |
Oops, something went wrong.