func unmarshalVolCreateRequest(msg *volume.VolCreateRequest, r *http.Request) (int, error) { e := utils.GetJSONFromRequest(r, msg) if e != nil { log.WithField("error", e).Error("Failed to parse the JSON Request") return 422, gderrors.ErrJSONParsingFailed } if msg.Name == "" { log.Error("Volume name is empty") return http.StatusBadRequest, gderrors.ErrEmptyVolName } if len(msg.Bricks) <= 0 { log.WithField("volume", msg.Name).Error("Brick list is empty") return http.StatusBadRequest, gderrors.ErrEmptyBrickList } return 0, nil }
func (c *Command) volumeCreate(w http.ResponseWriter, r *http.Request) { var msg volume.VolCreateRequest e := utils.GetJSONFromRequest(r, &msg) if e != nil { client.SendResponse(w, -1, 422, errors.ErrJSONParsingFailed.Error(), 422, "") return } if msg.Name == "" { log.Error("Volume name is empty") client.SendResponse(w, -1, http.StatusBadRequest, errors.ErrEmptyVolName.Error(), http.StatusBadRequest, "") return } if len(msg.Bricks) <= 0 { log.Error("Brick list is empty") client.SendResponse(w, -1, http.StatusBadRequest, errors.ErrEmptyBrickList.Error(), http.StatusBadRequest, "") return } if context.Store.VolumeExists(msg.Name) { log.WithField("Volume", msg.Name).Error("Volume already exists") client.SendResponse(w, -1, http.StatusBadRequest, errors.ErrVolExists.Error(), http.StatusBadRequest, "") return } vol := volume.NewVolumeEntry(msg) e = context.Store.AddOrUpdateVolume(vol) if e != nil { log.WithField("error", e).Error("Couldn't add volume to store") client.SendResponse(w, -1, http.StatusInternalServerError, e.Error(), http.StatusInternalServerError, "") return } // Creating client and server volfile volgen.GenerateVolfile(vol) log.WithField("volume", vol.Name).Debug("NewVolume added to store") client.SendResponse(w, 0, 0, "", http.StatusCreated, "") }
func addPeerHandler(w http.ResponseWriter, r *http.Request) { var req peer.PeerAddRequest if e := utils.GetJSONFromRequest(r, &req); e != nil { rest.SendHTTPError(w, http.StatusBadRequest, e.Error()) return } if len(req.Addresses) < 1 { rest.SendHTTPError(w, http.StatusBadRequest, errors.ErrNoHostnamesPresent.Error()) return } if req.Name == "" { req.Name = req.Addresses[0] } //TODO: Do proper validation before initiating the add process //FIXME: In the correct add process, the peer being probed would add it's details to the store once it's been validated. The code below is just a temporary stand-in to show how the API's would work p := &peer.Peer{ ID: uuid.NewRandom(), Name: req.Name, Addresses: req.Addresses, } rsp, e := client.ValidateAddPeer(&req) if e != nil { rest.SendHTTPError(w, http.StatusInternalServerError, *rsp.OpError) return } if e = peer.AddOrUpdatePeer(p); e != nil { rest.SendHTTPError(w, http.StatusInternalServerError, e.Error()) return } rest.SendHTTPResponse(w, http.StatusOK, nil) }
func addPeerHandler(w http.ResponseWriter, r *http.Request) { // FIXME: This is not txn based, yet. Behaviour when multiple simultaneous // add peer requests are sent to same node is unknown. var req PeerAddReq if e := utils.GetJSONFromRequest(r, &req); e != nil { rest.SendHTTPError(w, http.StatusBadRequest, e.Error()) return } if len(req.Addresses) < 1 { rest.SendHTTPError(w, http.StatusBadRequest, errors.ErrNoHostnamesPresent.Error()) return } // A peer can have multiple addresses. For now, we use only the first // address present in the req.Addresses list. remotePeerAddress, err := utils.FormRemotePeerAddress(req.Addresses[0]) if err != nil { rest.SendHTTPError(w, http.StatusBadRequest, err.Error()) return } // This remote call will return the remote peer's ID (UUID), name // and etcd peer url. remotePeer, e := ValidateAddPeer(remotePeerAddress, &req) if e != nil { rest.SendHTTPError(w, http.StatusInternalServerError, remotePeer.OpError) return } // TODO: Parse addresses considering ports to figure this out. if isPeerInCluster(remotePeer.UUID) { rest.SendHTTPError(w, http.StatusInternalServerError, "Peer already in cluster") return } // If user hasn't specified peer name, use the name returned by remote // peer which defaults to it's hostname. if req.Name == "" { req.Name = remotePeer.PeerName } // Adding a member is a two step process: // 1. Add the new member to the cluster via the members API. This is // performed on this node i.e the one that just accepted peer add // request from the user. // 2. Start the new member on the target node (the new peer) with the new // cluster configuration, including a list of the updated members // (existing members + the new member). newMember, e := etcdmgmt.EtcdMemberAdd("http://" + remotePeer.EtcdPeerAddress) if e != nil { log.WithFields(log.Fields{ "error": e, "uuid": remotePeer.UUID, "name": req.Name, "address": remotePeer.EtcdPeerAddress, }).Error("Failed to add member to etcd cluster.") rest.SendHTTPError(w, http.StatusInternalServerError, e.Error()) return } log.WithField("member-id", newMember.ID).Info("Added new member to etcd cluster") mlist, e := etcdmgmt.EtcdMemberList() if e != nil { log.WithField("error", e).Error("Failed to list members in etcd cluster") rest.SendHTTPError(w, http.StatusInternalServerError, e.Error()) return } // Member name of the newly added etcd member has not been set at this point. conf := []string{} for _, memb := range mlist { for _, u := range memb.PeerURLs { n := memb.Name if memb.ID == newMember.ID { n = remotePeer.UUID } conf = append(conf, fmt.Sprintf("%s=%s", n, u)) } } var etcdConf EtcdConfigReq etcdConf.EtcdName = remotePeer.UUID etcdConf.InitialCluster = strings.Join(conf, ",") etcdConf.ClusterState = "existing" log.WithField("initial-cluster", etcdConf.InitialCluster).Debug("Reconfiguring etcd on remote peer") etcdrsp, e := ConfigureRemoteETCD(remotePeerAddress, &etcdConf) if e != nil { log.WithField("err", e).Error("Failed to configure remote etcd") rest.SendHTTPError(w, http.StatusInternalServerError, etcdrsp.OpError) return } // Create a new peer object and add it to the store. p := &peer.Peer{ ID: uuid.Parse(remotePeer.UUID), Name: req.Name, Addresses: req.Addresses, MemberID: newMember.ID, } if e = peer.AddOrUpdatePeer(p); e != nil { log.WithFields(log.Fields{ "error": e, "peer/node": p.Name, }).Error("Failed to add peer into the etcd store") rest.SendHTTPError(w, http.StatusInternalServerError, e.Error()) return } body := map[string]uuid.UUID{"id": p.ID} rest.SendHTTPResponse(w, http.StatusCreated, body) }