Skip to content

Commit

Permalink
Promote slave to leader via GUI #53
Browse files Browse the repository at this point in the history
  • Loading branch information
svaroqui committed Sep 8, 2023
1 parent 32a5d6f commit 4d5277b
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 5 deletions.
5 changes: 5 additions & 0 deletions cluster/cluster_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ func (cluster *Cluster) IsURLPassDatabasesACL(strUser string, URL string) bool {
return true
}
}
if cluster.APIUsers[strUser].Grants[config.GrantClusterSwitchover] {
if strings.Contains(URL, "/actions/switchover") {
return true
}
}
if cluster.APIUsers[strUser].Grants[config.GrantDBKill] {
if strings.Contains(URL, "/actions/kill") {
return true
Expand Down
10 changes: 10 additions & 0 deletions cluster/cluster_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,16 @@ func (cluster *Cluster) GetGroupReplicationWhiteList() string {
return strings.Join(gcomms, ",")
}

func (cluster *Cluster) GetPreferedMasterList() string {
var prefmaster []string
for _, server := range cluster.Servers {
if server.Prefered {
prefmaster = append(prefmaster, server.URL)
}
}
return strings.Join(prefmaster, ",")
}

func (cluster *Cluster) GetGComm() string {
var gcomms []string
for _, server := range cluster.Servers {
Expand Down
6 changes: 3 additions & 3 deletions cluster/cluster_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,10 @@ func (cluster *Cluster) SetBenchMethod(m string) {
}

// SetPrefMaster is used by regtest test_switchover_semisync_switchback_prefmaster_norplcheck and API to force a server
func (cluster *Cluster) SetPrefMaster(PrefMaster string) {
cluster.Conf.PrefMaster = PrefMaster
func (cluster *Cluster) SetPrefMaster(PrefMasterURL string) {
cluster.Conf.PrefMaster = PrefMasterURL
for _, srv := range cluster.Servers {
if strings.Contains(PrefMaster, srv.URL) {
if strings.Contains(PrefMasterURL, srv.URL) {
srv.SetPrefered(true)
} else {
srv.SetPrefered(false)
Expand Down
2 changes: 1 addition & 1 deletion server/api_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ func (repman *ReplicationManager) handlerMuxSwitchover(w http.ResponseWriter, r
return
}
mycluster.LogPrintf(cluster.LvlInfo, "Rest API receive switchover request")
savedPrefMaster := mycluster.GetConf().PrefMaster
savedPrefMaster := mycluster.GetPreferedMasterList()
w.Header().Set("Access-Control-Allow-Origin", "*")
if mycluster.IsMasterFailed() {
mycluster.LogPrintf(cluster.LvlErr, "Master failed, cannot initiate switchover")
Expand Down
37 changes: 37 additions & 0 deletions server/api_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/codegangsta/negroni"
"github.com/gorilla/mux"
"github.com/signal18/replication-manager/cluster"
)

func (repman *ReplicationManager) apiDatabaseUnprotectedHandler(router *mux.Router) {
Expand Down Expand Up @@ -151,6 +152,10 @@ func (repman *ReplicationManager) apiDatabaseProtectedHandler(router *mux.Router
negroni.HandlerFunc(repman.validateTokenMiddleware),
negroni.Wrap(http.HandlerFunc(repman.handlerMuxServerMaintenance)),
))
router.Handle("/api/clusters/{clusterName}/servers/{serverName}/actions/switchover", negroni.New(
negroni.HandlerFunc(repman.validateTokenMiddleware),
negroni.Wrap(http.HandlerFunc(repman.handlerMuxServerSwitchover)),
))
router.Handle("/api/clusters/{clusterName}/servers/{serverName}/actions/unprovision", negroni.New(
negroni.HandlerFunc(repman.validateTokenMiddleware),
negroni.Wrap(http.HandlerFunc(repman.handlerMuxServerUnprovision)),
Expand Down Expand Up @@ -619,6 +624,38 @@ func (repman *ReplicationManager) handlerMuxServerMaintenance(w http.ResponseWri
}
}

func (repman *ReplicationManager) handlerMuxServerSwitchover(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
vars := mux.Vars(r)
mycluster := repman.getClusterByName(vars["clusterName"])
if mycluster != nil {
if !repman.IsValidClusterACL(r, mycluster) {
http.Error(w, "No valid ACL", 403)
return
}
node := mycluster.GetServerFromName(vars["serverName"])
if node != nil {
mycluster.LogPrintf(cluster.LvlInfo, "Rest API receive switchover request")
savedPrefMaster := mycluster.GetPreferedMasterList()
if mycluster.IsMasterFailed() {
mycluster.LogPrintf(cluster.LvlErr, "Master failed, cannot initiate switchover")
http.Error(w, "Leader is failed can not promote", http.StatusBadRequest)
return
}
mycluster.LogPrintf(cluster.LvlInfo, "API force for prefered leader: %s", node.URL)
mycluster.SetPrefMaster(node.URL)
mycluster.MasterFailover(false)
mycluster.SetPrefMaster(savedPrefMaster)
} else {
http.Error(w, "Server Not Found", 500)
return
}
} else {
http.Error(w, "Cluster Not Found", 500)
return
}
}

func (repman *ReplicationManager) handlerWaitInnoDBPurge(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
vars := mux.Vars(r)
Expand Down
5 changes: 5 additions & 0 deletions share/dashboard/app/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,8 @@ function (
}
};



$scope.rolling = function (fail) {
if (confirm("Confirm rolling restart")) httpGetWithoutResponse(getClusterUrl() + '/actions/rolling');
};
Expand All @@ -1016,6 +1018,9 @@ function (
$scope.dbmaintenance = function (server) {
if (confirm("Confirm maintenance for server-id: " + server)) httpGetWithoutResponse(getClusterUrl() + '/servers/' + server + '/actions/maintenance');
};
$scope.dbpromote = function (server) {
if (confirm("Confirm promotion for server-id: " + server)) httpGetWithoutResponse(getClusterUrl() + '/servers/' + server + '/actions/switchover');
};
$scope.dbjobs = function (server) {
if (confirm("Confirm running remote jobs for server-id: " + server)) httpGetWithoutResponse(getClusterUrl() + '/servers/' + server + '/actions/run-jobs');
};
Expand Down
8 changes: 7 additions & 1 deletion share/dashboard/static/menu-server.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
<md-icon md-menu-align-target class="fas fa-pause"></md-icon>
Maintenance Mode
</md-button>
</md-menu-item>
</md-menu-item>
<md-menu-item ng-click="dbpromote(server.id)">
<md-button ng-disabled="selectedCluster.apiUsers[user].grants['cluster-switchover']==false || server.isSlave==false">
<md-icon md-menu-align-target class="fas fa-star"></md-icon>
Promote To Leader
</md-button>
</md-menu-item>

<md-menu-item>
<md-menu>
Expand Down

0 comments on commit 4d5277b

Please sign in to comment.