Repository: VictoriaMetrics/VictoriaMetrics
Pull request #4747 (2023-07-31 09:41:26)

vmalert: remove deprecated in v1.79.0 web links with `*/status` suffix
Links of form `/api/v1/<groupID>/<alertID>/status` were deprecated in favour of `/api/v1/alerts?group_id=<>&alert_id=<>` links in v1.79.0. See more details here https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2825

This change removes code responsible for deprecated functionality.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/4747?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) Report
Patch coverage has no change and project coverage change: **`-0.06%`** :warning:
> Comparison is base [(`d18ff99`)](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/commit/d18ff993e67627e8c855c6862670c2aba4057277?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) 61.07% compared to head [(`b2a3369`)](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/4747?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) 61.02%.
> Report is 2 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #4747      +/-   ##
==========================================
- Coverage   61.07%   61.02%   -0.06%     
==========================================
  Files         381      380       -1     
  Lines       71616    71565      -51     
==========================================
- Hits        43740    43669      -71     
- Misses      25478    25513      +35     
+ Partials     2398     2383      -15     
```


| [Files Changed](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/4747?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) | Coverage Δ | |
|---|---|---|
| [app/vmalert/web.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/4747?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvd2ViLmdv) | `66.66% <0.00%> (+1.00%)` | :arrow_up: |

... and [11 files with indirect coverage changes](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/4747/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/4747?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).


Patch:
diff --git a/app/vmalert/README.md b/app/vmalert/README.md
index 4f06a6431..72077ebef 100644
--- a/app/vmalert/README.md
+++ b/app/vmalert/README.md
@@ -361,9 +361,9 @@ For recording rules to work `-remoteWrite.url` must be specified.
 
 ### Alerts state on restarts
 
-`vmalert` is stateless, it holds alerts state in the process memory. Restarting of `vmalert` process
-will reset alerts state in memory. To prevent `vmalert` from losing alerts state it should be configured
-to persist the state to the remote destination via the following flags:
+`vmalert` holds alerts state in the memory. Restart of the `vmalert` process will reset the state of all active alerts 
+in the memory. To prevent `vmalert` from losing the state on restarts configure it to persist the state 
+to the remote database via the following flags:
 
 * `-remoteWrite.url` - URL to VictoriaMetrics (Single) or vminsert (Cluster). `vmalert` will persist alerts state
   to the configured address in the form of [time series](https://docs.victoriametrics.com/keyConcepts.html#time-series)
diff --git a/app/vmalert/web.go b/app/vmalert/web.go
index ec24a3edb..3d91fb6aa 100644
--- a/app/vmalert/web.go
+++ b/app/vmalert/web.go
@@ -138,27 +138,8 @@ func (rh *requestHandler) handler(w http.ResponseWriter, r *http.Request) bool {
 		return true
 
 	default:
-		// Support of deprecated links:
-		// * /api/v1/<groupID>/<alertID>/status
-		// * <groupID>/<alertID>/status
-		// TODO: to remove in next versions
-
-		if !strings.HasSuffix(r.URL.Path, "/status") {
-			httpserver.Errorf(w, r, "unsupported path requested: %q ", r.URL.Path)
-			return false
-		}
-		alert, err := rh.alertByPath(strings.TrimPrefix(r.URL.Path, "/api/v1/"))
-		if err != nil {
-			httpserver.Errorf(w, r, "%s", err)
-			return true
-		}
-
-		redirectURL := alert.WebLink()
-		if strings.HasPrefix(r.URL.Path, "/api/v1/") {
-			redirectURL = alert.APILink()
-		}
-		httpserver.Redirect(w, "/"+redirectURL)
-		return true
+		httpserver.Errorf(w, r, "unsupported path requested: %q ", r.URL.Path)
+		return false
 	}
 }
 
@@ -302,41 +283,6 @@ func (rh *requestHandler) listAlerts() ([]byte, error) {
 	return b, nil
 }
 
-func (rh *requestHandler) alertByPath(path string) (*APIAlert, error) {
-	if strings.HasPrefix(path, "/vmalert") {
-		path = strings.TrimLeft(path, "/vmalert")
-	}
-	parts := strings.SplitN(strings.TrimLeft(path, "/"), "/", -1)
-	if len(parts) != 3 {
-		return nil, &httpserver.ErrorWithStatusCode{
-			Err:        fmt.Errorf(`path %q cointains /status suffix but doesn't match pattern "/groupID/alertID/status"`, path),
-			StatusCode: http.StatusBadRequest,
-		}
-	}
-	groupID, err := uint64FromPath(parts[0])
-	if err != nil {
-		return nil, badRequest(fmt.Errorf(`cannot parse groupID: %w`, err))
-	}
-	alertID, err := uint64FromPath(parts[1])
-	if err != nil {
-		return nil, badRequest(fmt.Errorf(`cannot parse alertID: %w`, err))
-	}
-	resp, err := rh.m.AlertAPI(groupID, alertID)
-	if err != nil {
-		return nil, errResponse(err, http.StatusNotFound)
-	}
-	return resp, nil
-}
-
-func uint64FromPath(path string) (uint64, error) {
-	s := strings.TrimRight(path, "/")
-	return strconv.ParseUint(s, 10, 0)
-}
-
-func badRequest(err error) *httpserver.ErrorWithStatusCode {
-	return errResponse(err, http.StatusBadRequest)
-}
-
 func errResponse(err error, sc int) *httpserver.ErrorWithStatusCode {
 	return &httpserver.ErrorWithStatusCode{
 		Err:        err,
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 916f83250..626f61e06 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -26,6 +26,7 @@ The following `tip` changes can be tested by building VictoriaMetrics components
 
 * FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): add `share_eq_over_time(m[d], eq)` function for calculating the share (in the range `[0...1]`) of raw samples on the given lookbehind window `d`, which are equal to `eq`. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4441). Thanks to @Damon07 for the [pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4725).
 * FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): remove deprecated in [v1.61.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.61.0) `-rule.configCheckInterval` command-line flag. Use `-configCheckInterval` command-line flag instead.
+* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): remove support of deprecated web links of `/api/v1/<groupID>/<alertID>/status` form in favour of `/api/v1/alerts?group_id=<>&alert_id=<>` links. Links of `/api/v1/<groupID>/<alertID>/status` form were deprecated in v1.79.0. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2825) for details.
 
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): use local scrape timestamps for the scraped metrics unless `honor_timestamps: true` option is explicitly set at [scrape_config](https://docs.victoriametrics.com/sd_configs.html#scrape_configs). This fixes gaps for metrics collected from [cadvisor](https://github.com/google/cadvisor) or similar exporters, which export metrics with invalid timestamps. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4697) and [this comment](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4697#issuecomment-1654614799) for details. The issue has been introduced in [v1.68.0](#v1680).
 
diff --git a/docs/vmalert.md b/docs/vmalert.md
index 384fd8c83..d941caf0c 100644
--- a/docs/vmalert.md
+++ b/docs/vmalert.md
@@ -372,9 +372,9 @@ For recording rules to work `-remoteWrite.url` must be specified.
 
 ### Alerts state on restarts
 
-`vmalert` is stateless, it holds alerts state in the process memory. Restarting of `vmalert` process
-will reset alerts state in memory. To prevent `vmalert` from losing alerts state it should be configured
-to persist the state to the remote destination via the following flags:
+`vmalert` holds alerts state in the memory. Restart of the `vmalert` process will reset the state of all active alerts 
+in the memory. To prevent `vmalert` from losing the state on restarts configure it to persist the state 
+to the remote database via the following flags:
 
 * `-remoteWrite.url` - URL to VictoriaMetrics (Single) or vminsert (Cluster). `vmalert` will persist alerts state
   to the configured address in the form of [time series](https://docs.victoriametrics.com/keyConcepts.html#time-series)


Test patch:
diff --git a/app/vmalert/web_test.go b/app/vmalert/web_test.go
index a036a586f..951e92e96 100644
--- a/app/vmalert/web_test.go
+++ b/app/vmalert/web_test.go
@@ -145,23 +145,6 @@ func TestHandler(t *testing.T) {
 			t.Errorf("expected 1 group got %d", length)
 		}
 	})
-
-	// check deprecated links support
-	// TODO: remove as soon as deprecated links removed
-	t.Run("/api/v1/0/0/status", func(t *testing.T) {
-		alert := &APIAlert{}
-		getResp(ts.URL+"/api/v1/0/0/status", alert, 200)
-		expAlert := ar.newAlertAPI(*ar.alerts[0])
-		if !reflect.DeepEqual(alert, expAlert) {
-			t.Errorf("expected %v is equal to %v", alert, expAlert)
-		}
-	})
-	t.Run("/api/v1/0/1/status", func(t *testing.T) {
-		getResp(ts.URL+"/api/v1/0/1/status", nil, 404)
-	})
-	t.Run("/api/v1/1/0/status", func(t *testing.T) {
-		getResp(ts.URL+"/api/v1/1/0/status", nil, 404)
-	})
 }
 
 func TestEmptyResponse(t *testing.T) {