Skip to content

Commit b787dd3

Browse files
Merge pull request #1459 from signal18/opensvc-fix-v3
add separate menu for app route updates
2 parents 575dfca + a01884c commit b787dd3

5 files changed

Lines changed: 87 additions & 1 deletion

File tree

cluster/cluster_acl_rules.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ var proxyACLRules = []ACLRule{
113113
var appACLRules = []ACLRule{
114114
{"/actions/provision", nil, []string{config.GrantProvAppProvision}},
115115
{"/service-opensvc", nil, []string{config.GrantProvAppProvision}},
116+
{"/actions/update-routes", nil, []string{config.GrantProvAppProvision}},
116117
{"/actions/unprovision", nil, []string{config.GrantProvAppUnprovision}},
117118
{"/actions/drop", nil, []string{config.GrantProvAppUnprovision}},
118119
{"/deployment/", nil, []string{config.GrantAppDeployment}},

server/api_app.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ func (repman *ReplicationManager) apiAppProtectedHandler(router *mux.Router) {
6969
negroni.HandlerFunc(repman.validateTokenMiddleware),
7070
negroni.Wrap(http.HandlerFunc(repman.handlerMuxAppProvision)),
7171
))
72+
router.Handle("/api/clusters/{clusterName}/apps/{appName}/actions/update-routes", negroni.New(
73+
negroni.HandlerFunc(repman.validateTokenMiddleware),
74+
negroni.Wrap(http.HandlerFunc(repman.handlerMuxAppUpdateRoutes)),
75+
)).Methods("POST")
7276
router.Handle("/api/clusters/{clusterName}/apps/{appName}/actions/stop", negroni.New(
7377
negroni.HandlerFunc(repman.validateTokenMiddleware),
7478
negroni.Wrap(http.HandlerFunc(repman.handlerMuxAppStop)),
@@ -829,6 +833,51 @@ func (repman *ReplicationManager) handlerMuxAppProvision(w http.ResponseWriter,
829833
}
830834
}
831835

836+
// @Summary Update App Routes
837+
// @Description Push route configuration to the OpenSVC gateway service for a given app
838+
// @Tags Apps
839+
// @Accept json
840+
// @Produce json
841+
// @Param Authorization header string true "Insert your access token" default(Bearer <Add access token here>)
842+
// @Param clusterName path string true "Cluster Name"
843+
// @Param appName path string true "App Name"
844+
// @Success 200 {string} string "App Routes Updated"
845+
// @Failure 403 {string} string "No valid ACL"
846+
// @Failure 404 {string} string "App Not Found"
847+
// @Failure 500 {string} string "Cluster Not Found"
848+
// @Router /api/clusters/{clusterName}/apps/{appName}/actions/update-routes [post]
849+
func (repman *ReplicationManager) handlerMuxAppUpdateRoutes(w http.ResponseWriter, r *http.Request) {
850+
w.Header().Set("Access-Control-Allow-Origin", "*")
851+
vars := mux.Vars(r)
852+
mycluster := repman.getClusterByName(vars["clusterName"])
853+
if mycluster != nil {
854+
if valid, _ := repman.IsValidClusterACL(r, mycluster); !valid {
855+
http.Error(w, "No valid ACL", http.StatusForbidden)
856+
return
857+
}
858+
859+
if mycluster.GetOrchestrator() != "opensvc" {
860+
http.Error(w, "Orchestrator not supported", http.StatusInternalServerError)
861+
return
862+
}
863+
864+
node := mycluster.GetAppFromName(vars["appName"])
865+
if node != nil {
866+
if err := mycluster.OpenSVCProvisionRoute(node); err != nil {
867+
http.Error(w, "Failed to update app routes: "+err.Error(), http.StatusInternalServerError)
868+
return
869+
}
870+
fmt.Fprintf(w, "App Routes Updated")
871+
} else {
872+
http.Error(w, "App Not Found", http.StatusNotFound)
873+
return
874+
}
875+
} else {
876+
http.Error(w, "Cluster Not Found", http.StatusInternalServerError)
877+
return
878+
}
879+
}
880+
832881
// @Summary Unprovision App Service
833882
// @Description Unprovision the app service for a given cluster and app
834883
// @Tags Apps

share/dashboard_react/src/Pages/Dashboard/components/Apps/AppMenu.jsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
provisionApp,
1010
startApp,
1111
stopApp,
12-
unprovisionApp
12+
unprovisionApp,
13+
updateRoutesApp
1314
} from '../../../../redux/clusterSlice'
1415
import { useNavigate } from 'react-router-dom'
1516

@@ -106,6 +107,18 @@ function AppMenu({ clusterName, row, isDesktop, colorScheme, from = 'tableView',
106107
}
107108
]
108109
: []),
110+
...(user?.grants['prov-app-provision'] && orchestrator === 'opensvc'
111+
? [
112+
{
113+
name: 'Update Routes',
114+
onClick: () => {
115+
openConfirmModal()
116+
setConfirmTitle(`Confirm update routes for ${appName}?`)
117+
setConfirmHandler(() => () => dispatch(updateRoutesApp({ clusterName, appId: row.id })))
118+
}
119+
}
120+
]
121+
: []),
109122
...(user?.grants['prov-app-unprovision']
110123
? [
111124
{

share/dashboard_react/src/redux/clusterSlice.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,6 +2080,21 @@ export const unprovisionApp = createGuardedAsyncThunk(
20802080
}
20812081
)
20822082

2083+
export const updateRoutesApp = createGuardedAsyncThunk(
2084+
'cluster/updateRoutesApp',
2085+
async ({ clusterName, appId }, thunkAPI) => {
2086+
try {
2087+
const baseURL = thunkAPI.getState()?.auth?.baseURL || ''
2088+
const { data, status } = await clusterService.updateRoutesApp(clusterName, appId, baseURL)
2089+
showSuccessBanner('Update routes successful!', status, thunkAPI)
2090+
return { data, status }
2091+
} catch (error) {
2092+
showErrorBanner('Update routes failed!', error, thunkAPI)
2093+
return handleError(error, thunkAPI)
2094+
}
2095+
}
2096+
)
2097+
20832098
export const startApp = createGuardedAsyncThunk('cluster/startApp', async ({ clusterName, appId }, thunkAPI) => {
20842099
try {
20852100
const baseURL = thunkAPI.getState()?.auth?.baseURL || ''
@@ -2700,6 +2715,7 @@ export const clusterSlice = createSlice({
27002715
clearProxy.pending,
27012716
provisionApp.pending,
27022717
unprovisionApp.pending,
2718+
updateRoutesApp.pending,
27032719
startApp.pending,
27042720
stopApp.pending,
27052721
abortApp.pending,
@@ -2785,6 +2801,7 @@ export const clusterSlice = createSlice({
27852801
clearProxy.fulfilled,
27862802
provisionApp.fulfilled,
27872803
unprovisionApp.fulfilled,
2804+
updateRoutesApp.fulfilled,
27882805
startApp.fulfilled,
27892806
stopApp.fulfilled,
27902807
abortApp.fulfilled,
@@ -2871,6 +2888,7 @@ export const clusterSlice = createSlice({
28712888
clearProxy.rejected,
28722889
provisionApp.rejected,
28732890
unprovisionApp.rejected,
2891+
updateRoutesApp.rejected,
28742892
startApp.rejected,
28752893
stopApp.rejected,
28762894
abortApp.rejected,

share/dashboard_react/src/services/clusterService.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ export const clusterService = {
159159
getClusterApps,
160160
provisionApp,
161161
unprovisionApp,
162+
updateRoutesApp,
162163
startApp,
163164
stopApp,
164165
abortApp,
@@ -741,6 +742,10 @@ function unprovisionApp(clusterName, appId, baseURL) {
741742
return getApi(baseURL).get(`clusters/${clusterName}/apps/${appId}/actions/unprovision`)
742743
}
743744

745+
function updateRoutesApp(clusterName, appId, baseURL) {
746+
return getApi(baseURL).post(`clusters/${clusterName}/apps/${appId}/actions/update-routes`)
747+
}
748+
744749
function startApp(clusterName, appId, baseURL) {
745750
return getApi(baseURL).get(`clusters/${clusterName}/apps/${appId}/actions/start`)
746751
}

0 commit comments

Comments
 (0)