Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #603 from rishubhjain/group
Browse files Browse the repository at this point in the history
Edit Zone API
  • Loading branch information
prashanthpai authored May 23, 2018
2 parents 7dd66b8 + 8ad368d commit 09f1358
Show file tree
Hide file tree
Showing 14 changed files with 164 additions and 76 deletions.
18 changes: 16 additions & 2 deletions glusterd2/commands/peers/addpeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package peercommands
import (
"fmt"
"net/http"
"strings"

"github.com/gluster/glusterd2/glusterd2/events"
"github.com/gluster/glusterd2/glusterd2/gdctx"
Expand All @@ -25,6 +26,13 @@ func addPeerHandler(w http.ResponseWriter, r *http.Request) {
return
}

for key := range req.Metadata {
if strings.HasPrefix(key, "_") {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, errors.ErrRestrictedKeyFound)
return
}
}

if len(req.Addresses) < 1 {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, errors.ErrNoHostnamesPresent)
return
Expand Down Expand Up @@ -84,7 +92,13 @@ func addPeerHandler(w http.ResponseWriter, r *http.Request) {
return
}

newpeer.MetaData = req.MetaData
if req.Zone != "" {
newpeer.Metadata["_zone"] = req.Zone
}
for key, value := range req.Metadata {
newpeer.Metadata[key] = value
}

err = peer.AddOrUpdatePeer(newpeer)
if err != nil {
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "Fail to add metadata to peer")
Expand All @@ -104,6 +118,6 @@ func createPeerAddResp(p *peer.Peer) *api.PeerAddResp {
Name: p.Name,
PeerAddresses: p.PeerAddresses,
ClientAddresses: p.ClientAddresses,
MetaData: p.MetaData,
Metadata: p.Metadata,
}
}
20 changes: 10 additions & 10 deletions glusterd2/commands/peers/editpeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func editPeer(w http.ResponseWriter, r *http.Request) {
return
}

for key := range req.MetaData {
for key := range req.Metadata {
if strings.HasPrefix(key, "_") {
logger.WithField("metadata-key", key).Error("Key names starting with '_' are restricted in metadata field")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "Key names starting with '_' are restricted in metadata field")
Expand All @@ -58,7 +58,7 @@ func editPeer(w http.ResponseWriter, r *http.Request) {
}
err = txn.Ctx.Set("peerid", peerID)
if err != nil {
logger.WithError(err).WithField("key", peerID).Error("Failed to set key in transaction context")
logger.WithError(err).WithField("key", "peerid").WithField("value", peerID).Error("Failed to set key in transaction context")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
return
}
Expand Down Expand Up @@ -102,13 +102,13 @@ func txnPeerEdit(c transaction.TxnCtx) error {
c.Logger().WithError(err).WithField("peerid", peerID).Error("Peer ID not found in store")
return err
}
for k, v := range req.MetaData {
if peerInfo.MetaData != nil {
peerInfo.MetaData[k] = v
} else {
peerInfo.MetaData = make(map[string]string)
peerInfo.MetaData[k] = v
}

for k, v := range req.Metadata {
peerInfo.Metadata[k] = v
}

if req.Zone != "" {
peerInfo.Metadata["_zone"] = req.Zone
}
err = peer.AddOrUpdatePeer(peerInfo)
if err != nil {
Expand Down Expand Up @@ -141,6 +141,6 @@ func createPeerEditResp(p *peer.Peer) *api.PeerEditResp {
Name: p.Name,
PeerAddresses: p.PeerAddresses,
ClientAddresses: p.ClientAddresses,
MetaData: p.MetaData,
Metadata: p.Metadata,
}
}
2 changes: 1 addition & 1 deletion glusterd2/commands/peers/getpeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ func createPeerGetResp(p *peer.Peer) *api.PeerGetResp {
PeerAddresses: p.PeerAddresses,
ClientAddresses: p.ClientAddresses,
Online: store.Store.IsNodeAlive(p.ID),
MetaData: p.MetaData,
Metadata: p.Metadata,
}
}
2 changes: 1 addition & 1 deletion glusterd2/commands/peers/getpeers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func createPeerListResp(peers []*peer.Peer) *api.PeerListResp {
PeerAddresses: p.PeerAddresses,
ClientAddresses: p.ClientAddresses,
Online: store.Store.IsNodeAlive(p.ID),
MetaData: p.MetaData,
Metadata: p.Metadata,
})
}

Expand Down
2 changes: 1 addition & 1 deletion glusterd2/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type Peer struct {
Name string
PeerAddresses []string
ClientAddresses []string
MetaData map[string]string
Metadata map[string]string
}

// ETCDConfig represents the structure which holds the ETCD env variables &
Expand Down
14 changes: 12 additions & 2 deletions glusterd2/peer/self.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net"

"github.com/gluster/glusterd2/glusterd2/gdctx"
"github.com/gluster/glusterd2/pkg/errors"

config "github.com/spf13/viper"
)
Expand Down Expand Up @@ -39,18 +40,27 @@ func normalizeAddrs() ([]string, error) {

// AddSelfDetails results in the peer adding its own details into etcd
func AddSelfDetails() error {
var err error

var err error
p := &Peer{
ID: gdctx.MyUUID,
Name: gdctx.HostName,
PeerAddresses: []string{config.GetString("peeraddress")},
}

p.ClientAddresses, err = normalizeAddrs()
if err != nil {
return err
}

peerInfo, err := GetPeer(gdctx.MyUUID.String())
if err == errors.ErrPeerNotFound {
p.Metadata = make(map[string]string)
p.Metadata["_zone"] = p.ID.String()
} else if err == nil && peerInfo != nil {
p.Metadata = peerInfo.Metadata
} else {
return err
}

return AddOrUpdatePeer(p)
}
10 changes: 6 additions & 4 deletions pkg/api/peer_req_resp.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,26 @@ type Peer struct {
PeerAddresses []string `json:"peer-addresses"`
ClientAddresses []string `json:"client-addresses"`
Online bool `json:"online"`
MetaData map[string]string `json:"metadata"`
Metadata map[string]string `json:"metadata"`
}

// PeerAddReq represents an incoming request to add a peer to the cluster
type PeerAddReq struct {
Addresses []string `json:"addresses"`
MetaData map[string]string `json:"metadata"`
Zone string `json:"zone,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}

// PeerEditReq represents an incoming request to edit metadata of peer
type PeerEditReq struct {
MetaData map[string]string `json:"metadata"`
Zone string `json:"zone"`
Metadata map[string]string `json:"metadata"`
}

// PeerAddResp is the success response sent to a PeerAddReq request
type PeerAddResp Peer

// PeerEditResp is the success response sent to a MetaDataEditReq request
// PeerEditResp is the success response sent to a PeerEditReq request
type PeerEditResp Peer

// PeerGetResp is the response sent for a peer get request
Expand Down
1 change: 1 addition & 0 deletions pkg/errors/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ var (
ErrUnmarshallFailed = errors.New("failed to unmarshall from json")
ErrClusterNotFound = errors.New("Cluster instance not found in store")
ErrDuplicateBrickPath = errors.New("Duplicate brick entry")
ErrRestrictedKeyFound = errors.New("Key names starting with '_' are restricted in metadata field")
ErrVolFileNotFound = errors.New("volume file not found")
)
5 changes: 1 addition & 4 deletions plugins/device/api/req.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ const (

// DeviceDisabled represents disabled
DeviceDisabled = "Disabled"

// DeviceFailed represents failed
DeviceFailed = "Failed"
)

// AddDeviceReq structure
type AddDeviceReq struct {
Devices []string `json:"devices"`
Device string `json:"device"`
}
2 changes: 1 addition & 1 deletion plugins/device/api/resp.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"github.com/gluster/glusterd2/pkg/api"
)

// Info represents structure in which devices are to be store in Peer MetaData
// Info represents structure in which devices are to be store in Peer Metadata
type Info struct {
Name string `json:"name"`
State string `json:"state"`
Expand Down
29 changes: 29 additions & 0 deletions plugins/device/deviceutils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package deviceutils

import (
"os/exec"
)

//CreatePV is used to create physical volume.
func CreatePV(device string) error {
pvcreateCmd := exec.Command("pvcreate", "--metadatasize=128M", "--dataalignment=256K", device)
return pvcreateCmd.Run()
}

//CreateVG is used to create volume group
func CreateVG(device string, vgName string) error {
vgcreateCmd := exec.Command("vgcreate", vgName, device)
return vgcreateCmd.Run()
}

//RemoveVG is used to remove volume group.
func RemoveVG(vgName string) error {
vgremoveCmd := exec.Command("vgremove", vgName)
return vgremoveCmd.Run()
}

//RemovePV is used to remove physical volume
func RemovePV(device string) error {
pvremoveCmd := exec.Command("pvremove", device)
return pvremoveCmd.Run()
}
50 changes: 38 additions & 12 deletions plugins/device/rest.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package device

import (
"encoding/json"
"net/http"

"github.com/gluster/glusterd2/glusterd2/gdctx"
Expand All @@ -18,52 +19,77 @@ func deviceAddHandler(w http.ResponseWriter, r *http.Request) {

ctx := r.Context()
logger := gdctx.GetReqLogger(ctx)
peerID := mux.Vars(r)["peerid"]
if uuid.Parse(peerID) == nil {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "Invalid peer-id passed in url")
return
}

req := new(deviceapi.AddDeviceReq)
if err := restutils.UnmarshalRequest(r, req); err != nil {
logger.WithError(err).Error("Failed to Unmarshal request")
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, errors.ErrJSONParsingFailed)
return
}
peerID := mux.Vars(r)["peerid"]
if peerID == "" {
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "peerid not present in request")

lock, unlock := transaction.CreateLockFuncs(peerID)
if err := lock(ctx); err != nil {
if err == transaction.ErrLockTimeout {
restutils.SendHTTPError(ctx, w, http.StatusConflict, err)
} else {
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
}
return
}
defer unlock(ctx)

peerInfo, err := peer.GetPeer(peerID)
if err != nil {
logger.WithError(err).WithField("peerid", peerID).Error("Peer ID not found in store")
if err == errors.ErrPeerNotFound {
restutils.SendHTTPError(ctx, w, http.StatusNotFound, errors.ErrPeerNotFound)
} else {
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "Failed to get peer from store")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "Failed to get peer details from store")
}
return
}

var devices []deviceapi.Info
err = json.Unmarshal([]byte(peerInfo.Metadata["_devices"]), &devices)
if err != nil {
logger.WithError(err).WithField("peerid", peerID).Error(err)
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
return
}
if checkIfDeviceExist(req.Device, devices) {
logger.WithError(err).WithField("device", req.Device).Error("Device already exists")
restutils.SendHTTPError(ctx, w, http.StatusBadRequest, "Device already exists")
return
}

txn := transaction.NewTxn(ctx)
defer txn.Cleanup()
lock, unlock, err := transaction.CreateLockSteps(peerInfo.ID.String())

txn.Nodes = []uuid.UUID{peerInfo.ID}
txn.Steps = []*transaction.Step{
lock,
{
DoFunc: "prepare-device",
Nodes: txn.Nodes,
},
unlock,
}
err = txn.Ctx.Set("peerid", peerID)
err = txn.Ctx.Set("peerid", &peerID)
if err != nil {
logger.WithError(err).Error("Failed to set data for transaction")
logger.WithError(err).WithField("key", "peerid").WithField("value", peerID).Error("Failed to set key in transaction context")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
return
}
err = txn.Ctx.Set("req", req)
err = txn.Ctx.Set("device", &req.Device)
if err != nil {
logger.WithError(err).Error("Failed to set data for transaction")
logger.WithError(err).WithField("key", "device").Error("Failed to set key in transaction context")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, err)
return
}

err = txn.Do()
if err != nil {
logger.WithError(err).Error("Transaction to prepare device failed")
Expand All @@ -72,7 +98,7 @@ func deviceAddHandler(w http.ResponseWriter, r *http.Request) {
}
peerInfo, err = peer.GetPeer(peerID)
if err != nil {
logger.WithError(err).Error("Failed to get peer from store")
logger.WithError(err).WithField("peerid", peerID).Error("Failed to get peer from store")
restutils.SendHTTPError(ctx, w, http.StatusInternalServerError, "Failed to get peer from store")
return
}
Expand Down
Loading

0 comments on commit 09f1358

Please sign in to comment.