Skip to content

Commit

Permalink
Merge remote-tracking branch 'couchbase/unstable' into HEAD
Browse files Browse the repository at this point in the history
Change-Id: Id5256942ba2923597dc46659c6ca224caf21c3cd
  • Loading branch information
jeelanp2003 committed Sep 25, 2019
2 parents df77b7a + 3efcb09 commit 52c1f60
Showing 1 changed file with 158 additions and 15 deletions.
173 changes: 158 additions & 15 deletions service_manager/http_handlers.go
Expand Up @@ -1258,6 +1258,11 @@ func (m *ServiceMgr) setSettings(appName string, data []byte) (info *runtimeInfo
return
}

if info = m.validateSettings(settings); info.Code != m.statusCodes.ok.Code {
logging.Errorf("%s %s", logPrefix, info.Info)
return
}

logging.Infof("%s Function: %s settings params: %+v", logPrefix, appName, settings)

_, procStatExists := settings["processing_status"]
Expand Down Expand Up @@ -1309,6 +1314,19 @@ func (m *ServiceMgr) setSettings(appName string, data []byte) (info *runtimeInfo

deployedApps := m.superSup.GetDeployedApps()
if pOk && dOk {
var isMixedMode bool
if isMixedMode, info = m.isMixedModeCluster(); info.Code != m.statusCodes.ok.Code {
logging.Errorf("%s %s", logPrefix, info.Info)
return
}

if isMixedMode && !m.isUndeployOperation(app.Settings) {
info.Code = m.statusCodes.errMixedMode.Code
info.Info = "Life-cycle operations except delete and undeploy are not allowed in a mixed mode cluster"
logging.Errorf("%s %s", logPrefix)
return
}

// Resetting dcp_stream_boundary to everything during undeployment
if !processingStatus && !deploymentStatus {
app.Settings["dcp_stream_boundary"] = common.DcpEverything
Expand Down Expand Up @@ -2498,6 +2516,10 @@ func (m *ServiceMgr) functionsHandler(w http.ResponseWriter, r *http.Request) {
functionsName := regexp.MustCompile("^/api/v1/functions/(.*[^/])/?$") // Match is agnostic of trailing '/'
functionsNameSettings := regexp.MustCompile("^/api/v1/functions/(.*[^/])/settings/?$")
functionsNameRetry := regexp.MustCompile("^/api/v1/functions/(.*[^/])/retry/?$")
functionsDeploy := regexp.MustCompile("^/api/v1/functions/(.*[^/])/deploy/?$")
functionsUndeploy := regexp.MustCompile("^/api/v1/functions/(.*[^/])/undeploy/?$")
functionsPause := regexp.MustCompile("^/api/v1/functions/(.*[^/])/pause/?$")
functionsResume := regexp.MustCompile("^/api/v1/functions/(.*[^/])/resume/?$")

if match := functionsNameRetry.FindStringSubmatch(r.URL.Path); len(match) != 0 {
appName := match[1]
Expand Down Expand Up @@ -2578,32 +2600,153 @@ func (m *ServiceMgr) functionsHandler(w http.ResponseWriter, r *http.Request) {
m.sendErrorInfo(w, info)
return
}
var isMixedMode bool
if isMixedMode, info = m.isMixedModeCluster(); info.Code != m.statusCodes.ok.Code {
m.sendErrorInfo(w, info)
return
}

if isMixedMode && !m.isUndeployOperation(settings) {
info.Code = m.statusCodes.errMixedMode.Code
info.Info = "Life-cycle operations except delete and undeploy are not allowed in a mixed mode cluster"
if info = m.setSettings(appName, data); info.Code != m.statusCodes.ok.Code {
m.sendErrorInfo(w, info)
return
}
default:
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
} else if match := functionsPause.FindStringSubmatch(r.URL.Path); len(match) != 0 {
info := &runtimeInfo{}
if r.Method != "POST" {
info.Code = m.statusCodes.errInvalidConfig.Code
info.Info = fmt.Sprintf("Only POST call allowed to this endpoint")
m.sendErrorInfo(w, info)
}
appName := match[1]

if info = m.validateSettings(settings); info.Code != m.statusCodes.ok.Code {
m.sendErrorInfo(w, info)
return
}
audit.Log(auditevent.SetSettings, r, appName)

if info = m.setSettings(appName, data); info.Code != m.statusCodes.ok.Code {
var settings = make(map[string]interface{})
settings["deployment_status"] = true
settings["processing_status"] = false
settings["dcp_stream_boundary"] = "everything"

data, err := json.MarshalIndent(settings, "", " ")
if err != nil {
info.Code = m.statusCodes.errMarshalResp.Code
info.Info = fmt.Sprintf("failed to marshal function settings, err : %v", err)
logging.Errorf("%s %s", logPrefix, info.Info)
m.sendErrorInfo(w, info)
return
}

if info = m.setSettings(appName, data); info.Code != m.statusCodes.ok.Code {
m.sendErrorInfo(w, info)
return
}

} else if match := functionsResume.FindStringSubmatch(r.URL.Path); len(match) != 0 {
info := &runtimeInfo{}
if r.Method != "POST" {
info.Code = m.statusCodes.errInvalidConfig.Code
info.Info = fmt.Sprintf("Only POST call allowed to this endpoint")
m.sendErrorInfo(w, info)
}
appName := match[1]

audit.Log(auditevent.SetSettings, r, appName)

var settings = make(map[string]interface{})
settings["deployment_status"] = true
settings["processing_status"] = true
settings["dcp_stream_boundary"] = "from_prior"

data, err := json.MarshalIndent(settings, "", " ")
if err != nil {
info.Code = m.statusCodes.errMarshalResp.Code
info.Info = fmt.Sprintf("failed to marshal function settings, err : %v", err)
logging.Errorf("%s %s", logPrefix, info.Info)
m.sendErrorInfo(w, info)
return
}

if info = m.setSettings(appName, data); info.Code != m.statusCodes.ok.Code {
m.sendErrorInfo(w, info)
return
}

} else if match := functionsDeploy.FindStringSubmatch(r.URL.Path); len(match) != 0 {
info := &runtimeInfo{}
if r.Method != "POST" {
info.Code = m.statusCodes.errInvalidConfig.Code
info.Info = fmt.Sprintf("Only POST call allowed to this endpoint")
m.sendErrorInfo(w, info)
}
appName := match[1]

audit.Log(auditevent.SetSettings, r, appName)

data, err := ioutil.ReadAll(r.Body)
if err != nil {
info.Code = m.statusCodes.errReadReq.Code
info.Info = fmt.Sprintf("failed to read request body, err: %v", err)
logging.Errorf("%s %s", logPrefix, info.Info)
m.sendErrorInfo(w, info)
return
}

settings := make(map[string]interface{})
if len(data) != 0 {
err = json.Unmarshal(data, &settings)
if err != nil {
info.Code = m.statusCodes.errMarshalResp.Code
info.Info = fmt.Sprintf("%v failed to unmarshal setting supplied, err: %v", len(data), err)
logging.Errorf("%s %s", logPrefix, info.Info)
m.sendErrorInfo(w, info)
return
}
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}

settings["deployment_status"] = true
settings["processing_status"] = true

data, err = json.MarshalIndent(settings, "", " ")
if err != nil {
info.Code = m.statusCodes.errMarshalResp.Code
info.Info = fmt.Sprintf("failed to marshal function settings, err : %v", err)
logging.Errorf("%s %s", logPrefix, info.Info)
m.sendErrorInfo(w, info)
return
}

if info = m.setSettings(appName, data); info.Code != m.statusCodes.ok.Code {
m.sendErrorInfo(w, info)
return
}

} else if match := functionsUndeploy.FindStringSubmatch(r.URL.Path); len(match) != 0 {
info := &runtimeInfo{}
if r.Method != "POST" {
info.Code = m.statusCodes.errInvalidConfig.Code
info.Info = fmt.Sprintf("Only POST call allowed to this endpoint")
m.sendErrorInfo(w, info)
}
appName := match[1]

audit.Log(auditevent.SetSettings, r, appName)

var settings = make(map[string]interface{})
settings["deployment_status"] = false
settings["processing_status"] = false

data, err := json.MarshalIndent(settings, "", " ")
if err != nil {
info.Code = m.statusCodes.errMarshalResp.Code
info.Info = fmt.Sprintf("failed to marshal function settings, err : %v", err)
logging.Errorf("%s %s", logPrefix, info.Info)
m.sendErrorInfo(w, info)
return
}

if info = m.setSettings(appName, data); info.Code != m.statusCodes.ok.Code {
m.sendErrorInfo(w, info)
return
}

} else if match := functionsName.FindStringSubmatch(r.URL.Path); len(match) != 0 {
appName := match[1]
switch r.Method {
Expand Down

0 comments on commit 52c1f60

Please sign in to comment.